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

徐小夕 等级 653 0 0

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

背景介绍

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

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

(单纯使用ajax或者fetch实现get请求时)
当我们在该页面将列表切换到第二页时,浏览器url并没有变化,所以将链接复制给其他人打开并不会将列表结果切换到第二页,而是重新初始化。

实现过程

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

location.search = '?page=2';

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

《前端实战总结》如何在不刷新页面的情况下改变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() 会抛出一个异常。该参数是可选的,缺省为当前URL

实现

/**
 * 设置浏览器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等前端知识和实战,欢迎在公众号《趣谈前端》加入我们一起学习讨论,共同探索前端的边界。

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

更多推荐

收藏
评论区

相关推荐

《前端实战总结》如何在不刷新页面的情况下改变URL
由于公司最近有个需求是想让我们的get请求的参数都直接显示在浏览器url上,这样我们就可以直接通过复制url来显示对应的界面数据了。 背景介绍 由于我们常用的http请求一般是基于XHR对象的实现或者fetch实现,这种请求操作并不会触发浏览器url的变化,这样虽然也能正常请求数据并渲染到页面,但是如果用户在当前页面操作了某个get请求并得到了某条数据,想
mock 请求分发
首发于 <a name"vqeCn"</a 背景是这样的我们公司的后管项目走的不是 resful 风格的 api,而是走后管网关,后管网关会将请求进行分发,具体怎么分发,有这么以下几点: 请求全部走 POST 请求 URL 统一为 /agrs 数据提交方式为 application/json 数据格式大致分为: 系统报文头
从输入URL到页面渲染完成
从输入URL到页面渲染完成涉及网络、浏览器工作原理等知识。 前序知识 浏览器进程结构textBrowser进程 负责协调、主控,包括地址栏、书签、历史栈。GPU进程 负责整个浏览器界面的渲染网络进程 负责发起接收网络请求插件进程 控制网页中使用到的插件 如flash 渲染器进程 默认使用(Processpersiteinstance)模式 四种
H5调取APP或跳转至下载
#### 来源:   最近在配合移动端做几个详情页h5分享页面,需要调取App并跳转至app详情页, 如果没有安装App,需要判断引导至下载页面。 #### 参考文档: [https://juejin.im/post/5b7efb2ee51d45388b6af96c](https://www.oschina.net/action/GoToLink?u
Java 通过get post 请求url
1️⃣.已获取小程序的access\_token 为例,通过Get请求url 1 import com.alibaba.fastjson.JSONObject; 2 3 String wechatUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=clie
Java乱码
1.Javascript传参乱码: 在浏览器端对要传递的中文参数进行编码处理.代码如下: xmlhttp.open("POST",url,true); //请求参数初始化 xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //因为请求方式为PO
thinkphp url模式
入口文件是应用的单一入口,对应用的所有请求都定向到应用入口文件,系统会从URL参数中解析当前请求的模块、控制器和操作: 1. `http://serverName/index.php/模块/控制器/操作` 这是3.2版本的标准URL格式。 > 可以通过设置模块绑定或者域名部署等方式简化URL地址中的模块及控制器名称。 URL大小写 ------
thinkphp5 不用主机配置URL重写
可以通过URL重写隐藏应用的入口文件index.php,下面是相关服务器的配置参考: \[ Apache \] httpd.conf配置文件中加载了mod\_rewrite.so模块 AllowOverride None 将None改为 All 把下面的内容保存为.htaccess文件放到应用入口文件的同级目录下 <IfModule mod
URL编码以及get和post请求乱码问题
1.  什么是URL编码。 > URL编码是一种浏览器用来打包表单输入的格式,浏览器从表单中获取所有的name和其对应的value,将他们以name/value编码方式作为URL的一部分或者分离的发送到服务器上。 2.  URL编码规则。 > 每对name/value由&分开,每对来自表单的name/value用=分开。如果用户没有输入值的那个
url的使用
1.urls.py   默认是在主目录中,主路由配置文件,会包含最基本的地址映射,并且每个地址访问都必须要先经过该文件。   作用:通过 urls中定义好的地址找到对应的视图处理函数   urlpatterns = \[     url()   \] 2.url() 的语法   作用:为了匹配用户的访问路径   语法:    
VideoView支持播放https的url视频
重写setVideoUrI方法 @Override public void setVideoURI(Uri uri) { super.setVideoURI(uri); try { HttpsURLConnection.setDefaultSSLSocketFactory(S
Cocos Creator 获取当前URL取参数
利用Javascript获取当前页的URL,这个问题起来好像很复杂,如果第一次去想这个问题,很多人估计又在琢磨到底又是哪个神一般的Javascript函数。 其实不是,Javascript获取当前页的URL的函数就是我们经常用来重定向的window.location.href。 比如如下函数:  1. <script>   2. var url=w
CodeIgniter的URL URI
\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。而URL是uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locat
HttpURLConnection(http 1.1) 用法、状态码、状态描述
最近研究了java的HttpURLConnection的用法, 这里简单的做一下记录: Java中可以使用HttpURLConnection来请求WEB资源。 **1、 URL请求的类别** 分为二类,GET与POST请求。二者的区别在于:       a:) get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet,
Javascript如何获取URL地址栏参数
在页面之间传递参数的时候最常用的莫过于GET方式,倘若利用PHP获取参数则很简单,但是如果是静态页面,该如何取得地址后边的那些参数呢?下边的代码通过正则匹配的方法获取参数值并返回,代码十分简单,但是却十分实用,不足之处就是每次只能选一个参数。 <script type="text/javascript" lang="javascript">