Phenomenon of the problem
A similar requirement occurs in service scenarios. Upon entering page A, the user initiates a request to check the user identity. If the user does not meet the requirements for operating the page, a pop-up message is displayed indicating that the user is switched to login page B. After going to page B, click the browser back button to return to page A, and find that page A did not reload and execute JS, so there was no prompt for user identity judgment.
Why clicking the browser forward/Back button does not re-execute js
Back-forward cache
Bfcache is a strategy to give users a smoother experience when using the browser’s forward/Back buttons. This is a strong caching strategy. DOM, Window, JS objects, and XHR can all be cached when the browser is clicked forward/back, but the caching strategy varies from browser to browser. The cache state is not cleared until the user closes the browser.
pageShow
For browsers with bfCache policy, you can use the PagesHow event (IE does not support it) if you want to define some behavior after the page is reloaded from the cache. A pagesHow event is triggered when a session history is executed, whether from cache or not.
The pageShow event is similar to the onLoad event, in general
- When the page is loaded for the first time: onLoad and pageShow will be triggered successively;
- Click the browser back button from another page: onload will not be triggered (Chrome onload will be triggered on the desktop), pageShow will most likely be triggered (Chrome, FireFox, Safari)
Check whether the page is from the cache:
-
E.persisted: you can determine whether the page is from the cache according to e.persisted in the pageShow event object. The return value is bool. If the value is true, the page is from the cache. However, the performance of e. server is different in different browsers, and it is not reliable to rely only on E. server.
-
Window. The performance. Navigation. Type = = = 2: performance. The navigation object type field has the following conditions:
- 0: Click links, bookmarks, and form submissions, or script actions, or enter the address directly in the URL
- 1: Click the refresh page button or use the location.reload () method
- 2: The page is accessed through history and forward and backward
- 255: Any other way
But this way of judgment, it is will be abandoned Navigation Timing the window. The Level 1 standard performance. Navigation object contains the type field. It is recommended to use Navigation Timing window in Level 2. The performance. GetEntriesByType (” Navigation “) [0]. The type of judgment
-
Window. The performance. GetEntriesByType (” navigation “) [0]. Type = = = ‘back_forward’ : which type field has the following situation:
- ‘navigate’: click links, bookmarks and form submissions, either for script actions or to enter the address directly in the URL
- ‘Reload ‘: Click the refresh page button or through the location.reload () method
- ‘back_forward’: The page is accessed through history and forward and backward
- ‘PRERender ‘: Navigated from prerender Link
To sum up, the following pageShow can be obtained to solve the ios BfCache problem
window.addEventListener('pageshow', function (event) { if (event.persisted || (window.performance && window.performance.getEntriesByType && String(window.performance.getEntriesByType('navigation')[0].type) === 'back_forward')) { location.reload(); }}Copy the code
Some Android browsers do not use the BfCache policy to speed up page display
For browsers that use the BfCache policy, they can use pageShow to listen for uninitialized loading operations. However, some Android browsers (such as Xiaomi, UC, QQ and some other browsers) do not use the BFCache policy, but encapsulate the page into a form similar to webView. In this case, The visiBilityChange event determines whether the load is initialized.
-
Visibilitychange, which is compatible with browsers other than Safari, triggers this event when the visible line of the page changes, such as when tabs switch between visible and hidden
-
Document. visibilityState has visible, Hidden, and PRERender values
- Hidden: The page is completely invisible
- Visible: at least part of the page is visible
- Prerender: The page is about to render or is rendering and is not visible
-
The listener is as follows (mount listener on window for compatibility) :
window.addEventListener("visibilitychange", function() { console.log(document.visibilityState); If (document.visiBilityState == "hidden") {console.log(' hidden '); } else if (document.visibilityState == "visible") {console.log(' display ')}});Copy the code
Third, summary
For ios BFCache, it can determine whether the page is from the cache by pageShow, and Android can determine whether the current visibility of the page changes by monitoring visiBilityChange events to determine subsequent operations, which is basically compatible with most models and scenarios.
Avoid caching by other means
cache-control
Cache-control: no-cache, no-store, must-revalidate, which forces the page to be loaded from the service, can be set to disable caching in HTTP request/response headers. However, because ios supports BFCache, this method is invalid on ios and can be used in most scenarios.
You can also use meta tags, sometimes not supported by browsers like Chrome:
<META HTTP-EQUIV="pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate">
<META HTTP-EQUIV="expires" CONTENT="0">
Copy the code
The random number
For caching requests, random numbers (such as timestamp “? Timestamp =” + new Date().gettime ()) avoid caching.