-
先说结论,以下是可行的方法
- 1.添加参数让每次请求不一样,如
new Date().getTime()或Math.random() - 2.
jQuery请求设置cache: false - 3.设置
xhr.setRequestHeader("Cache-Control", "no-cache")或者xhr.setRequestHeader("If-Modified-Since", "0")
function initData() { $.ajax({ type: 'GET', url: 'https://iiter.cn/api/soup', dataType: 'json', // cache: false, data: { // t: new Date().getTime() // t: Math.random() }, beforeSend: function(xhr) { // xhr.setRequestHeader("Cache-Control", "no-cache"); // xhr.setRequestHeader("If-Modified-Since", "0") }, success: function(res) { console.log(res.data); } }); } initData();五处注释对应五种方法,任意一种即可。
- 1.添加参数让每次请求不一样,如
-
问题
- 页面上有一个按钮,按钮是否可以点击由服务器返回;用户点击按钮发送请求后,按钮变成不可点击状态;这个时候如果用户点击跳转到其他页面,然后再返回回来,会发现按钮又变成可点击的状态了。虽然服务器会兜底校验,但是这样容易让用户困扰,所以需要解决。
-
测试环境
Google Chrome版本100.0.4896.127(正式版本) (x86_64)- 注意:我在调试过程中,打开控制台后即使取消勾选
Disable Cache,也会刷新页面,可能是我设置的问题,所以调试过程中不要打开浏览器控制台,查看接口请求情况可以使用抓包工具查看
-
网上查到的解决方法
window.addEventListener('pageshow', function(event) { if (event.persisted || window.performance && window.performance.navigation.type == 2) { // do somethineg... } }, false); -
这里简单写个
demo,用到的接口是之前收藏的免费接口,本地可以直接请求- 接入
function initData() { alert('initData'); } initData(); window.addEventListener('pageshow', function(event) { if (event.persisted || window.performance && window.performance.navigation.type == 2) { initData(); } }, false);- 执行结果:打开
A页面,alert一次,之后跳转到B页面,再次返回,alert两次 - 结论:返回操作,会重新渲染页面,执行页面
js;按说这样就不会出现上边提到的问题,下面我们把alert换成ajax请求再试试;
- 执行结果:打开
- 再次接入
function initData() { $.ajax({ type: 'GET', url: 'https://iiter.cn/api/soup', dataType: 'json', data: {}, success: function(res) { console.log(res.data); } }); } initData(); window.addEventListener('pageshow', function(event) { if (event.persisted || window.performance && window.performance.navigation.type == 2) { initData(); } }, false);- 执行结果:重复
A页面到B页面,再从B页面返回,抓包发现只有在A页面首次加载的时候,才会发起请求 - 结论&猜测:这不和上一次的运行结果矛盾了吗?
initData方法应该会重新执行的,为什么没发现重新发出请求呢?猜测浏览器可能在请求一样的情况下,就不会重新发出请求,而是直接使用缓存的旧数据。再改写一下demo测试一下。
- 执行结果:重复
- 再再次接入
function initData() { $.ajax({ type: 'GET', url: 'https://iiter.cn/api/soup', dataType: 'json', data: { t: new Date().getTime() }, success: function(res) { console.log(res.data); } }); } initData(); window.addEventListener('pageshow', function(event) { if (event.persisted || window.performance && window.performance.navigation.type == 2) { initData(); } }, false);- 执行结果,重复,发现一共发出了三次请求,情况和第一次接入效果吻合,可以确定第二次的猜测成立。但是这样重复请求,有些浪费资源,再优化一下
- 再再再次接入
var ajax_count = 0; function initData() { $.ajax({ type: 'GET', url: 'https://iiter.cn/api/soup', dataType: 'json', data: { t: ajax_count }, success: function(res) { console.log(res.data); } }); } initData(); window.addEventListener('pageshow', function(event) { if (event.persisted || window.performance && window.performance.navigation.type == 2) { ajax_count = localStorage.getItem('ajax_count') ? localStorage.getItem('ajax_count') : 0; ajax_count = ajax_count - 0 + 1; localStorage.setItem('ajax_count', ajax_count); initData(); } }, false);- 执行结果:一开始是没使用
localStorage,发现只有第一次操作是正常的,后面又不会重新请求接口了。猜测只要是重复了的,就不会再重新请求,所以使用localStorage存一下,保证每次都是不同的,得到了想要的结果。
- 执行结果:一开始是没使用
- 最终优化
function initData() { $.ajax({ type: 'GET', url: 'https://iiter.cn/api/soup', dataType: 'json', data: { t: new Date().getTime() }, success: function(res) { console.log(res.data); } }); } initData();- 结论:发现完全可以不使用网上查到的
pageshow,只要保证每次请求参数不同就可以了。
- 结论:发现完全可以不使用网上查到的
- 接入
-
踩坑经验
- 浏览器返回操作会重新渲染页面、执行所有
js,但是只要是浏览器曾经请求过的接口,就不会重新请求,而是使用缓存的旧数据,这时候就要通过修改请求参数,实现想要的效果。
- 浏览器返回操作会重新渲染页面、执行所有