origin
Many front-end developers have encountered different issues with GET requests from different browsers. A common get request for the same URL after an Ajax request:
Case 1 sometimes returns 304, sometimes returns 200; Case 2: Sometimes 304 is always returned regardless of background data changes, sometimes 200 is always returned; The same set of code results differently in different browsers;Copy the code
Disabling browsers from caching data is a common solution on the Web
1. Set Meta tags on the HTML page
<meta http-equiv="Cache-Control" content="no-store"/>
<meta http-equiv="Pragma" content="no-cache"/>
<meta http-equiv="Expires" content="0"/>
Copy the code
Result: Depending on the browser or the version of the same browser, this method has great compatibility, and many times it doesn't work at all.Copy the code
2. Add time stamps or random numbers to ajax URL parameters
$.ajax({
url: 'http://localhost/api/list'.type: 'get'.data: {
_t: new Date().valueOf() // Add a timestamp
//_t: math.random () + random number
},
success: function ( res ) {
console.log(res); }})Copy the code
Result: While this approach solves the problem of IE always returning 304, virtually every Ajax request to the server is not the best solution for Web optimization.Copy the code
3. Replace the GET request with a POST request
Result: Not recommended, because this approach is not RESTful API design, and because this approach also calls the server every time, does not really take advantage of the browser's built-in caching capabilities.Copy the code
What you want to achieve
200 is returned for the first time. If the data remains unchanged, the request must confirm with the server that 304 is returned. If the data has changed, 200 is returned and the Internet Explorer and Google browsers must be consistent.
Browser caching mechanism
Browser cache is mainly composed of HTML Meta tag control cache and HTTP header information control cache. In addition, it is also related to user behavior. HTTP header information parameters are many and lack relevant practical experience, so it is complicated to understand and difficult to remember. You can refer to the HTTP cache policy
Client-specific testing
Service side: Express provides interface, client side: jquery Ajax request, packet capture tool Fiddler, only tests cache-Control and Pragma
// The server does not set the response header, ordinary output, each output data does not change
app.get('/list'.(req, res, next) = >{
Order.findAll({ where: { uuid: req.session.loginUser } }).then(result= >{
res.send({code:0.msg: 'Obtain success'.data: result});
}).catch(err= >{
res.send({code: -1.data: 'Fetch failed'}); })});// The client sets the request headers cache-control and Pragma
$.ajax({
url: 'http://localhost/api/list'.type: 'get'.headers: {
// If only cacahe-control: 'no-cache' is set, IE always returns 304. The packet capture tool cannot capture the packet, and the request is not confirmed by the server
// When cacahe-control: 'no-cache' is set, Google always returns 200. The packet capture tool can grab packets and request to retrieve data from the server again, without using the browser's cache function
'cache-control': 'no-cache'.Pragma: 'no-cache' Pragma: 'no-cache' Pragma: 'no-cache' Pragma: 'no-cache' Pragma: 'no-cache' Pragma: 'no-cache' Pragma: 'no-cache
// When only Pragma: 'no-cache' is set, Google browser always returns 200. The packet capture tool can catch all packets and request to retrieve data from the server again, without taking advantage of the browser's caching capabilities
'Pragma': 'no-cache'
// If the two parameters are not set at the same time, Internet Explorer always returns 304. The packet capture tool fails to capture packets, and the request is not confirmed by the server
// If both parameters are not set, Google browser returns 200 for the first time, and always returns 304 after that, with confirmation with the server
// If the two parameters are set at the same time, Internet Explorer always returns 200. The packet capture tool can capture all packets and request to obtain data from the server again, without using the cache function of the browser
// When both parameters are set at the same time, Google browser always returns 200. The packet capture tool can catch all packets and request to retrieve data from the server again, without using the browser's cache function
},
success: function (res) {
console.log(res); }})Copy the code
Results:Copy the code
If the Pragma parameter is set to “no-cache”, Internet Explorer and Google get data from the server with the same effect every time, but never from the cache. If cache-control is set to “no-cache”, Internet Explorer is invalid and Google is not effective. So the above approach ended in failure.
Testing on the server side
Discard the request header and set the response header. Client: jquery Ajax request, server Express provides interface, packet capture tool fiddler, only set server ‘cache-control’
// on the server, set the response header cache-control
app.get('/list'.(req, res, next) = >{
res.set( {
'Cache-Control' : 'max-age=5' // Easy to test, set the cache time 5s;}); Order.findAll({where: { uuid: req.session.loginUser } }).then(result= >{
res.send({code:0.msg: 'Obtain success'.data: result});
}).catch(err= >{
res.send({code: -1.data: 'Fetch failed'}); })});// The client, plain Ajax, does not do any request header Settings
$.ajax({
url: 'http://localhost/api/list'.type: 'get'.headers: {},success: function (res) {
console.log(res);
}
})
Copy the code
Internet Explorer test result
Internet Explorer response header:
Internet Explorer Ajax request:
Google Browser test results
Google Browser response header:
Google Chrome Ajax request:
Conclusion: The response header cache time is set for 5s on the backend and not on the front-end. After the first request is received by Internet Explorer, each request is obtained from the cache within 5 seconds, and 304 is directly returned without confirmation from the server. After 5 seconds, 304 is confirmed with the server. If the server data changes, 200 is returned. And so on for subsequent requests. After the first request, Googole browser will fetch each request from cache within 5s without confirming with the server. The network panel displays code 200,size from cache. After 5s, the server will confirm with the server. And so on for subsequent requests. This method is in line with what I want. If you want to check with the server every time and not fetch directly from the cache, just set cache-control: ‘max-age: 0’ on the back end.
Note: With ajax libraries such as $jquery Ajax, Angular-Resource, vue-resouce, Axios, native Ajax, etc., the default request header may not be the same as the one I set above, and the result may not be the same. The same goes for the back end.