《前端实战总结》如何在不刷新页面的情况下改变UR

由于公司最近有个需求是想让我们的get请求的参数都直接显示在浏览器url上,这样我们就可以直接通过复制url来显示对应的界面数据了。

背景介绍

由于我们常用的http请求一般是基于XHR对象的实现或者fetch实现,这种请求操作并不会触发浏览器url的变化,这样虽然也能正常请求数据并渲染到页面,但是如果用户在当前页面操作了某个get请求并得到了某条数据,想通过链接将当前看到的界面分享给其他人时,那么此时浏览器url并不会变化,通过链接只能访问到初始化的数据界面,此时并不能达到理想的效果。如下图所示:

(单纯使用ajax或者fetch实现get请求时)

当我们在该页面将列表切换到第二页时,浏览器url并没有变化,所以将链接复制给其他人打开并不会将列表结果切换到第二页,而是重新初始化。

实现过程

通过以上的背景和问题,我们可以想想可以怎么实现呢?我的第一个反应就是使用location API来实现,我们可以使用location.search来读写浏览器query参数:

location.search = '?page=2';

这段代码虽然可以改变浏览器url,如下图所示:

但会出现一个性能问题,就是当我们执行了以上代码后,整个浏览器都会刷新,导致我们不想刷新的部分也刷新了,那我们有办法可以让它局部刷新吗?答案是必须有。

这里就要引出我们本文的重点:history API。

history API

Window.history是一个只读属性,用来获取History 对象的引用,History 对象提供了操作浏览器会话历史(浏览器地址栏中访问的页面,以及当前页面中通过框架加载的页面)的接口。HTML5引入了 history.pushState() 和 history.replaceState() 方法,它们分别可以添加和修改历史记录条目。

使用 history.pushState() 可以改变referrer,它在用户发送 XMLHttpRequest 请求时在HTTP头部使用,改变state后创建的 XMLHttpRequest 对象的referrer都会被改变。因为referrer是标识创建 XMLHttpRequest 对象时 this 所代表的window对象中document的URL。

那么我们就可以使用pushState来实现我们的更新浏览器url功能了。

pushState() 方法

pushState() 需要三个参数: 一个状态对象, 一个标题 (目前已忽略), 和 (可选的) 一个URL:

  • 状态对象 — 状态对象state是一个JavaScript对象,通过pushState () 创建新的历史记录条目。无论什么时候用户导航到新的状态,popstate事件就会被触发,且该事件的state属性包含该历史记录条目状态对象的副
  • 标题 — Firefox 目前忽略这个参数,但未来可能会用到。在此处传一个空字符串应该可以安全的防范未来这个方法的更改。或者,你可以为跳转的state传递一个短标
  • URL — 该参数定义了新的历史URL记录。注意,调用 pushState() 后浏览器并不会立即加载这个URL,但可能会在稍后某些情况下加载这个URL,比如在用户重新打开浏览器时。新URL不必须为绝对路径。如果新URL是相对路径,那么它将被作为相对于当前URL处理。新URL必须与当前URL同源,否则 pushState() 会抛出一个异常。该参数是可选的,缺省为当前UR

实现

/**
 * 设置浏览器url
 *  params:queryObj(参数对象)
*/
function setBrowserUrl(queryObj){
    // stringify是queryString的一个api,具体可以查看node官网,也可以自己实现
    var url = `${location.pathname}?${stringify(queryObj)}`
    history.pushState({url: url}, '', url)
}

这样我们就可以在请求的同时,调用setBrowserUrl方法来改变浏览器url了。接下来我们就可以监听浏览器url的变化,如果浏览器url有需要的请求参数,那么我们就根据请求参数来请求数据,没有就初始化页面,这样当我们查看某条记录或者某个小秘密时,想把该数据保存下来并分享给被人,是不是就可以实现了呢?

总结

基于H5 history可以实现很多优雅使用的工具,比如路由,缓存控件等等。

如果想了解更多webpack,gulp,css3,javascript,nodeJS,canvas等前端知识和实战,欢迎在公众号《趣谈前端》加入我们一起学习讨论,共同探索前端的边界。

本文分享自微信公众号 - 趣谈前端(beautifulFront)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-10-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏APP测试

HTTP响应状态码:除了404,还有啥?

2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。

9120
来自专栏搜云库技术团队

有赞服务化架构演进

服务化是互联网公司成长的必经之路。随着微服务的兴起,很多公司如火如荼的搞起了自己的服务化,有兴奋有无奈。那服务化该怎么做,该做什么?本文试图从有赞的发展历程来体...

12130
来自专栏搜云库技术团队

Dubbo服务消费者调用过程

首先通过 ReferenceConfig类的 private void init()方法会先检查初始化所有的配置信息后,调用 privateT createPr...

9340
来自专栏用户5521492的专栏

Python | 分析 Ajax 爬取今日头条街拍美图

这次实战采取的是 wi10 + python3.6 + PyCharm 的开发环境。另外,还用到了 requests 、urllib、hashlib、multi...

14830
来自专栏SEO-网站优化

关于全部已知导致百度索引量下降的原因分析及解决方案

索引量是流量的基础,索引量数据的每一个变动都拨动着站长敏感的神经,“索引量下降之后该如何着手分析”一直是各位讨论的热门话题。这次站长社区版主老吕又拔刀相助了,看...

10720
来自专栏APP测试

Jmeter&badboy环境搭建

注:如果电脑没有安装JDK,那么一定要记得,提前安装好JDK,并配置好环境变量哦。

16220
来自专栏HACK学习

FCKeditor文件上传漏洞及利用

FCKeditor是一个网页的文本编辑器,在很多的cms里都有出现。近日工作期间遇到了不下十个有FCKeditor的站,尤其是ZF网站。

20440
来自专栏java大数据

javascript当中window open用法

5.window.open 例 5.1(onload&onunloadIEFF.html) <!DOCTYPE HTML PUBLIC "-//W3C//DTD...

10430
来自专栏搜云库技术团队

技术变化那么快,学 Docker 看这篇就够了

来源:juejin.im/post/5bffdb645188251b8a270058

13010
来自专栏用户5521492的专栏

RESTful API 设计规范

它的大原则容易把握,但是细节不容易做对。本文总结 RESTful 的设计细节,介绍如何设计出易于理解和使用的 API。

16630

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励