在 HTML 中强制缓存脚本

Posted

技术标签:

【中文标题】在 HTML 中强制缓存脚本【英文标题】:Force caching script in HTML 【发布时间】:2022-01-21 22:19:53 【问题描述】:

是否可以文件?

例如,给定一个脚本应答器 <script src="https://example-server.com/external/widget.js" type="text/javascript" async></script>,它将位于网站每个页面的 head 中。

是否有可能只从服务器获取一次但在每个页面都执行它?

我的目标是能够使用 https://example-server.com/external/widget.js 脚本中的内容而不是 html 的其余部分来处理它。我想在不增加服务器容量的情况下向客户端提供脚本。

免责声明:https://example-sever.com 不存在,只是为了提供有效的 URI。

正如@KooiInc 所指出的,浏览器会自动处理文件缓存。

但我的问题仍然存在,URI https://example-server.com/external/widget.js 重定向到缓存的 https://cdn.net/assets/widget-fingerprints.js。但是第一个 URI 没有被缓存。

回答@Tejas Sarade 的问题:

https://example-server.com/external/widget.js 的标头

General >
    Request URL: https://example-server.com/external/widget.js
    Request Method: GET
    Status Code: 302 Found
    Referrer Policy: strict-origin-when-cross-origin
Responses Headers >
    Cache-Control: no-cache
    Connection: keep-alive
    Content-Type: text/javascript; charset=utf-8
    Location: https://cdn.net/assets/widget-fingerprints.js
    Referrer-Policy: strict-origin-when-cross-origin
    ...

https://cdn.net/assets/widget-fingerprints.js 的标头

General >
    Request URL: https://cdn.net/assets/widget-fingerprints.js
    Request Method: GET
    Status Code: 200  (from disk cache)
    Referrer Policy: strict-origin-when-cross-origin
Response Headers >
    Cache-Control: no-cache
    Connection: keep-alive
    Content-Type: text/javascript; charset=utf-8
    ...
    x-cache: Hit from cloudfront
    ...

编辑:

一点上下文。因为我认为问题可能与 Rails 资产管道和/或我的 CDN 配置有关。

我在 Rails 上使用 ruby​​,而不是直接使用 assets 路由服务我的资产,我决定重定向到重定向到我的控制器中的 assets_url 以完美控制我的路由。 (我的控制器要复杂得多,我只是在写相关部分)

class WidgetsController < ApplicationController

  WIDGET_FILE_NAME = 'widget'

  def index
    respond_to do |format|
      format.js  redirect_to asset_url(WIDGET_FILE_NAME) 
    end
  end
end

在我的routes.rb 文件中

  scope :external do
    resources :widget, only: [:index], controller: :widgets
  end

因此我可以使用端点 GET https://example-server.com/external/widget.js 而不是 GET https://example-server.com/assets/widget.js

【问题讨论】:

浏览器有自己的caching mechanism。基本上一旦你的脚本被加载一次并且没有改变,就会使用一个缓存的版本。 嘿@KooiInc,非常感谢您的链接,非常有用。我已经编辑了我的答案,以便您更好地了解我的需求。 如果您可以控制服务器 example-server.com,您可以向 HTTP 响应添加标头,这会告诉浏览器应该如何处理缓存。有关这些标头的更多详细信息,请访问 web.dev/http-cache @Kruupös https://example-server.com/external/widget.js的响应状态码是什么? 【参考方案1】:

这是有道理的。 根据 HTTP 协议,默认情况下不缓存 302 响应,除非响应标头指示。 cache-control: max-age=in_secondsExpires: specific_date

https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

或者您可以只使用 301 重定向,除非响应标头指示不缓存,否则浏览器默认会缓存这些重定向。

如何设置响应标头或更改类型或重定向取决于您使用的服务器类型。

【讨论】:

【参考方案2】:

您可以使用查询字符串创建动态网址

<script>document.write('<script src="/myJavascript.js?dev=' + Math.floor(Math.random() * 100) + '"\><\/script>');</script>

这样浏览器会将脚本加载为新文件

【讨论】:

感谢@Yassine XM 的回答,但这与我想做的完全相反:强制脚本考虑完全相同。

以上是关于在 HTML 中强制缓存脚本的主要内容,如果未能解决你的问题,请参考以下文章

是否会缓存扩展名为php的html脚本标签中的脚本?

html 只需脚本以避免仅使用javascript在js / css文件中缓存。

动态脚本文件仍然过期

Express 错误:根据 HTML 规范对模块脚本强制执行严格的 MIME 类型检查

怎样清除浏览器缓存?

强制脚本在 Python 3 中运行