preface

Recently, I often see browser cache on the back of exams. Although I haven’t used it, I know its role and importance from its description. But there is still no code practice, but also a little understanding, this tone can not swallow ah, began to look for information, but most of the theory is half a line of code, finally put together Epiphany. Start building environment, work.

Browser cache

The browser cache is a way for the browser to store recently requested documents on the local disk. When a visitor visits the same page again, the browser can load documents directly from the local disk. Browser caches are divided into strong caches (also known as local caches) and negotiated caches (also known as weak caches).

  • Strong cache

When a resource is requested, if it was previously requested and strong caching is used, the request will not be sent to the server for the resource during the expiration period, but will be fetched directly from the browser cache (regardless of whether the resource has changed). Expired will be fetched from the server again, and strong cache again.

  • Negotiate the cache

When requesting a resource, if the resource is previously requested and the negotiation cache is used, or if the request is sent to the server, the server verifies that the resource is not modified and returns the 304 status code through logical judgment, then the resource is obtained from the cache this time. If it is confirmed that the resource has been modified, the resource is resend to the client and the client updates the cache.

There are two criteria to determine whether a resource has been modified. One is to determine whether the last modification time has changed (indeed, it has been modified, but the content of the resource can not be changed), and the other is to determine whether the content of the resource has been modified.

Using a cache has the following advantages:

  • Reduce redundant data transmission
  • Reduce server load
  • Speed up the loading of web pages by clients

Set up the environment

  • Creating a folderappAnd create it underapp.js and fs/a.txt(Write random things inside)

  • We use thenode+koa2To set up the environment we need, install koA, install routing
npm install koa --save
npm install koa-router --save
Copy the code
  • app.js
var Koa = require('koa'); var app = new Koa(); var Router = require('koa-router')(); const fs = require('fs') Router.get("/", Async (CTX) => {ctx.body = "OK"}) app.use (router.routes ()) // Start router.use (router.allowedMethods ()); app.listen(3000);Copy the code

Start the server and enter the website address 127.0.0.1:3000 to set up the environment successfully

Strong cache

Strong caching is controlled using the Expires and cache-control fields in the HTTP header. Expires is the HTTP1.0 specification, and cache-control was introduced in HTTP1.1. We use cache-Control here as an example.

Cache-control has some commonly set values

  • Private: only the browser can cache (default value).
  • Public: the browser and proxy server can cache.
  • Max-age = XXX: indicates the expiration time in seconds.
  • No-cache: does not cache strongly.
  • No-store: no strong cache, no negotiation cache)

Change the code above/route to

Router.get('/', async (ctx) => { const getResource = () => { return new Promise((res) => { fs.readFile("./fs/a.txt", (err, data) => { if (err) { return; } res(data)})})} ctx.set(' cache-control ', 'max-age=10') // Set strong Cache, expiration time is 10 seconds ctx.body = await getResource(); })Copy the code

Close the test Setup page and open it again to access 127.0.0.1:3000

More front-end page response headersCache-ControlThis field, which is cached locally for 10 seconds, does not request the serverIf you request the resource again within the expiration time, you can see that the request did not go through the server

Negotiate the cache

Two sets of header fields are involved: Etag and if-none-match, last-Modified and if-Modified-since.

EtagandIf-None-Match

Etag/ if-none-match returns a check code. ETag ensures that each resource is unique, and changes in resources lead to changes in ETag. The server determines whether the cache is hit based on the if-none-match value sent by the browser. When the server returns a 304 Not Modified response, because the ETag has been regenerated, the response header returns the ETag even though the ETag has Not changed.

Last-Modifyandif-modified-since

When the browser requests a resource for the first time, last-modify is added to the header returned by the server. Last-modify indicates the time when the resource was Last modified, for example, last-modify: Thu,31 Dec 2037 23:59:59 GMT.

When the browser requests the resource again, the request header contains if-modified-since, which is the last-modify value returned before the cache. After receiving if-modified-since, the server determines whether the resource hit the cache based on the last modification time.

If the cache is hit, 304 is returned, the resource content is not returned, and last-modify is not returned.

For example, we use last-modify and if-modified-since. The implementation of Etag and if-none-match reads the content of the resource, converts it to a hash value, and then does much the same with last-modify and if-Modified-since implementations.

A new router is added

Router.get('/pp', async (ctx) => { const ifModifiedSince = ctx.request.header['if-modified-since']; const getResource = () => { return new Promise((res) => { fs.stat("./fs/a.txt", (err, stats) => { if (err) { console.log(err); } res(stats) }) }) } let resource = await getResource(); Atime Access Time Time when a file was last accessed (read or executed) // ctime Change Time Time when a file (property or permission) or directory (property or permission) was last changed // mtime The Modify Time modified Time / / last modified files (content) or directory (content) of Time if (ifModifiedSince = = = resource. Mtime. ToGMTString ()) {/ / convert date to (according to GMT) the string ctx.status = 304; } ctx.set('Last-Modified', resource.mtime.toGMTString()); ctx.body = resource })Copy the code

Close the page and open the page again to access 127.0.0.1:3000/pp

For the first request, there is no if-Modified-since field

The second request, without modifying the resource, returns the status code 304 and retrits the resource from the cache

Request the server again when modifying the contents of the a.txt file

conclusion

Go ahead and rub out the code