Understanding browser return from window.history does not trigger page refresh problem

1. Basic concepts

The DOM window object provides access to the browser's session history through the history object, which exposes a number of useful methods and properties that allow you to jump forward and backward in the user's browsing history, and - starting with HTML5 - Provides operations on the contents of the history stack.

Second, page jump

前进一页:window.history.forward();
后退一页:window.history.back();
后退两页:window.history.go(-2);

Third, view the number of pages in the history stack

That is, the total number of pages that can appear by clicking the forward and backward of the browser all the time.

window.history.length;

4. The phenomenon that the browser returns without triggering a page refresh

When returning to the previous page in the IOS WeChat built-in browser, the previous page will not be refreshed.
Usually, in the browser caching mechanism, in the operation of returning to the previous page, dynamic and static resources such as html/css/js/interface will not be re-requested, but js will be reloaded. But in the IOS WeChat page, js will also save the last executed state of the previous page, and js will not be re-executed.
The caching mechanism of this mode can speed up the rendering speed, but some data needs to be frequently displayed and edited, which will lead to out of sync. For example, the 'details page' jumps to the 'edit page', and then returns to the 'details page' after editing. If the data display of the 'details page' has not been modified synchronously, it is definitely unacceptable.
In the mixed app mode of webview and 5+, you will also encounter the problem of returning to the previous page without refreshing.
I encountered that page a of project A jumps to page b of project B. After modifying the value, such as the payment amount, click the back button to return to page a of project A, which will not trigger the refresh of page a, resulting in no update of the amount .

Five, the reason why the browser returns without triggering a page refresh

Browser forward/backward cache (Backward/Forward Cache, BF Cache), of course some people call it disk Cache.
BF Cache is a browser optimization. The HTML standard does not specify how to cache, so the cache behavior is implemented by each browser, so it is not the same.
Setting no-cache via header caching has no effect since it is not an HTTP cache. Of course, BF Cache cannot be understood with the HTTP caching mechanism.
Therefore, as long as we know that the current page is in the ios environment, and it is returned, and it is obtained from the cache, then we can force it to refresh.

Six, the solution

With ageshow, this event fires when the page is shown, whether the page is from bfcache or not. In reloading the page, pageshow will be triggered after the load event is triggered; and for the page in bfcache, pageshow will be triggered at the moment when the page state is fully restored. Also note that although this event targets document, its event handler must be added to window.
It is worth noting that now our front-end pages are all developed on a single page, so routing jumps in our own projects will not have this problem. Because we use vue-router to simulate the routing jump, it is not a real window change, so the pageShow event will not be triggered. (Recall that our pages actually share the same index.html. The code of the page is mounted on the page through the label. The page jump of our single-page project is actually just the same page constantly switching components That's all).
To trigger pageShow, you need to jump to another window and then return, such as Baidu page.

const equipmentType = navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
  ? 'ios'
  : navigator.userAgent.indexOf('Android') > -1 ||
    navigator.userAgent.indexOf('Adr') > -1
  ? 'android'
  : 'others';
window.addEventListener('pageshow', e => {
    
    
  // persisted: 判断是否存在 BF Cache
  // performance.navigation.type: 页面通过历史记录和前进后退访问时,type值为2
  if (
    equipmentType == 'ios' &&
    router.options.history.location == '/home' &&
    (e.persisted ||
      (window.performance && window.performance.navigation.type == 2))
  ) {
    
    
    location.reload();
  }
});

In addition to the usual properties, the event object for the pageshow event also contains a boolean property called persisted. If the page is saved in bfcache, the value of this attribute is true; but this attribute alone is not enough, so when window.performance.navigation.type=2 is added, it means that the generated page is returned.

Guess you like

Origin blog.csdn.net/weixin_42349568/article/details/129255270