Recently, I found that the JS code I packaged was not updated after being uploaded to the server. Think of using NG to do the proxy, may be ng cache problem, I looked up information to learn about HTTP (1.1) cache things.

1. Related terms :(conventionreqIs the request header,resResponse headers,CThe client,SThe service side)

// Response Headers HTTP/1.1 200 OK Server: nginx Date: Wed, 04 Dec 2019 09:11:07 GMT Content-Type: text/ CSS Vary: Accept-Encoding Last-Modified: Wed, 04 Dec 2019 09:03:18 GMT ETag: W/"5de77656-2340" Expires: Wed, 04 Dec 2019 21:11:06 GMT Cache-Control: max-age=43200 Content-Encoding: gzipCopy the code
  • Expires.resWhere is the expiration time of the resource
  • Last-modified:resIs the time when the resource was last modified
  • ETag:resUnique identifier of the resource in (hash generated)
  • The if-modified-since:reqThe time when the resource was last modified
  • If None – Match:reqResource identification in
  • Cache-control:res.reqRepresents the cache policy
  1. reqCommon instruction in
The field names instructions
max-age= Sets the maximum period for which the cache is stored, after which the cache is considered expired in seconds. withExpiresInstead, time is relative to the time requested
max-stale[=] CCan receive a resource that has expired. Sets an optional number of seconds to not accept resources that exceed the given time
min-fresh= CWants to get an object that will remain up to date for the specified number of secondsres
no-cache The cache is forced to submit the request to the original server for validation before publishing the cache copy
no-store Nothing about client requests or server responses is cached
  1. res(Repeat instructions in REQ are not listed, see MDN for details)
The field names instructions
public Indicates that the response can be cached by any object (including the client that sent the request, the proxy server, and so on), even content that is not normally cacheable
private Indicates that the response can only be cached by a single user and not as a shared cache (that is, the proxy server cannot cache it). A private cache can cache the response content
must-revalidate Once the resource expires (e.gmax-age), the cache cannot respond to subsequent requests with this resource until successfully validated to the original server
proxy-revalidate withmust-revalidateThe same effect, but it only applies to shared caches (such as proxies) and is ignored by private caches
s-maxage= covermax-ageorExpiresHeader, but only for shared caches (such as individual agents) and ignored by private caches

Last-modified and if-modified-since, ETag and if-none-match are used in each RES and REq Match.

2. Common cache scenarios :(the convention resource is app.js)

  1. Expires.
    • process

      1. CClient requestapp.js —-> SEnd.
      2. SThe responseapp.jsExpires —-> CEnd. (CSide cacheapp.jsuntilExpires)
      3. if 1Occur in theExpiresBefore, it’s going to fetch the else directly from the cache2
      4. Repeat the above
    • advantage

      Compared to the original uncached request and corresponding, the advantage is obvious, it will be directly fetched from the cache, reducing the number of request responses

    • defects

      If app.js changes in Expires, the resource presented on the C-end is not up to date.

  2. Expires + last-modified:
    • process

      1. CClient requestapp.js —-> Send
      2. SThe responseapp.jsExpires.Last-Modified —-> CEnd. (CSide cacheapp.jsuntilExpires, the last modified time isLast-Modified)
        • if 1Occur in theExpiresBefore, (200) is fetched directly from the cache.
        • else CClient requestSEnd,If-Modified-SincePhi is equal to the corresponding last timeLast-Modified)
        • SEnd usereqIn theIf-Modified-SinceandresIn theLast-ModifiedComparison.
          • If consistent, responseCEnd: You can continue to use local cache (304)
          • else,2
      3. Repeat the above
    • advantage

      Instead of just using Expires, if app.js changes and the cache can be updated, the C-side renders the content up to date, and the else doesn’t have a new res pulled once and reads the cache directly

    • defects

      Last-modified is accurate to the second. In fact, there are many REQS and RES that can be completed in a second, so the problem is obvious

      • inLast-ModifiedInside,app.jsIt’s been modified multiple times, soCThe end will still read from the cache, rendering content is not up to date
      • Assume that in avue-cliUnder development, for some reason, the code didn’t actually change, but CI/CD repeated builds packaged the file,app.jsInto theapp01.js(different versions of the hash name generated by build.js), but the code only changes the name, the content does not change, but pulls the resource again
  3. Expires + last-Modified + ETag:
    • process

      1. CClient requestapp.js —-> Send
      2. SThe responseapp.jsExpires.Last-Modified ,ETag—-> CEnd. (CSide cacheapp.jsuntilExpires, the last modified time isLast-Modified, the file id isETag)
        • if 1Occur in theExpiresBefore, (200) is fetched directly from the cache.
          • else CClient requestSEnd,If-Modified-SincePhi is equal to the corresponding last timeLast-Modified) andIf-None-MatchPhi is equal to the corresponding last timeEtag)
            • SEnd usereqIn theIf-None-MatchandresIn theEtagThe comparison,ignoreoffIf-Modified-SinceandLast-ModifiedComparison. (ifEtagChange,Last-ModifiedConstant change, sufficient condition)
            • If consistent, responseCEnd: You can continue to use local cache (304)
            • else,2
      3. Repeat the above
    • advantage

      Compared with the previous method, the verification of resource changes is more strict.

    • defects

      Let’s imagine a situation where we’re constantly changing app.js, packaging and building, and for some reason we don’t want the latest app.js to be displayed on the C side, but read the latest one after a while, which obviously doesn’t meet our requirements

  4. Expires + last-Modified + ETag + cache-control:
    • process

      1. CClient requestapp.js —-> Send
      2. SThe responseapp.jsExpires.Last-Modified ,ETag.Cache-Control: Max – age = 43200 — — — — >CEnd. (CEnd found withCache-Control: Max – age = 43200,ignoreExpires *, rememberLast-Modified ,ETag)
        • if 1In (reqOccurrence time + 12h(43200s)), (200) is taken directly from the cache.
          • else CClient requestSEnd,If-Modified-SincePhi is equal to the corresponding last timeLast-Modified) andIf-None-MatchPhi is equal to the corresponding last timeEtag)
            • SEnd usereqIn theIf-None-MatchandresIn theEtagThe comparison,ignoreoffIf-Modified-SinceandLast-ModifiedComparison. (ifEtagChange,Last-ModifiedConstant change, sufficient condition)
            • If consistent, responseCEnd: You can continue to use local cache (304)
            • else,2
      3. Repeat the above
    • advantage

      We achieved what our last plan couldn’t

    • Defect?

      C end cannot actively know the change of resources requested by us on S end, but can only passively learn from RES. Is this a defect?

3. Common problems :(the convention resource is app.js)

  1. How to set not caching?

    • Ng configuration is as follows:

      Location / {access_log /data/nginx/log/xxx.log API; root /home/www/html; if ($request_filename ~ .*\.(htm|html)$) { add_header Cache-Control no-cache; }}Copy the code
    • Package HTML to set meta tags as follows

      <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
      <meta http-equiv="Pragma" content="no-cache" />
      <meta http-equiv="Expires" content="0" />
      Copy the code

      Meta is used to simulate HTTP response headers in HTML documents. Meta tags are used for web pages. Meta has two types of attributes: name and http-equiv. The name attribute is mainly used to describe web pages, corresponding to content (web page content), so as to facilitate search engine robots to search and classify (almost all search engines use online robots to automatically search meta values to classify web pages). The most important of these are description (search engine description of the site) and keywords (category keywords), so you should add a meta value to each page.

  2. How do I clear the cache?

    • Nginx Enterprise edition provides purger functionality. For community edition Nginx consider using ngx_cache_purge (which is a good way to restrict access to Nginx, such as only allowing Intranet access or requiring a password) github.com/FRiCKLE/ngx…

      Location ~ /purge(/.*) {allow 127.0.0.1; deny all; proxy_cache_purge cache$1$is_args$args; }Copy the code

      PS: The ngx_CACHE_purge module is automatically installed in Ng such as the Pagoda panel, as described below.

    • Find the cache folder and kill it.

  3. What steps are checked if a cache error occurs?

    1. Check whether the wrong folder is uploaded
      • Open the packaged JS of the project and checkapp.jsThe file name.
      • Open the browser consoleNetworkTo check thejs.F5After refreshing, find the corresponding app.xxx.js and compare. If you find out the names are different andresThe head Last –ModifiedNo, there’s a good chance you’re uploading the wrong folder.
    2. Check to see if the update is correct
      • Record stageETag
      • Refresh after re-uploading and compare twiceETagAre consistent
    3. Check whether ng is correctly configuredServer
    4. Comb through the build deployment steps, step by step (you only get so far)

Just HTTP (1.1) part of the common scenarios, so far here is enough, we have to step by step, do not be swallowed

Thinking is limited, unavoidably appear omissions, welcome you to point out, pool wisdom.

Welcome to pay attention to my public account “Web Engineer self-cultivation”, exchange and learn together ~

reference
  1. HTTP Caching for Interviews juejin.cn/post/684490…
  2. Mdn-cache-control developer.mozilla.org/zh-CN/docs/…
  3. The introduction to the cache-control HTTP blog.csdn.net/u012375924/…
  4. The Nginx cache configuration and Nginx ngx_cache_purge module using “www.cnblogs.com/Eivll0m/p/4…