浏览器从缓存中加载JS文件,但不会加载CSS文件。

4
当浏览我的网站时,浏览器会从缓存中加载JS文件,但不会加载CSS文件。这在本地服务器和现场(包括我和其他用户)都会出现,因为日志显示大多数加载的是.css文件。我尝试了其他解决方案(example):我点击超链接(而不是刷新),我的Chrome Devtools没有选中“禁用缓存”。以下是初始请求(使用CTRL+F5进行硬刷新):

enter image description here

然后返回该页面会创建另一个请求:

enter image description here

(注意:第二个请求中没有发送Cache-Control,证明我确实没有刷新)
如预期的那样,服务器对.css文件做出304未修改响应,但我不明白为什么它还要去服务器(请注意下面.js文件是在没有服务器请求的情况下检索到的)。

enter image description here

我相信您可以通过访问https://up.codes在自己的计算机上直接查看问题。我正在使用Chrome 71.0。

为什么CSS文件没有被缓存?


我不明白你的问题是什么,你需要什么?如果没有这些信息,没有人会回答你。请问你想写下来吗? - Bharata
@Garrett,我刚刚检查了你的网站,我的端口缓存了所有的CSS文件。第一次下载后,它们中的所有文件都会显示状态304 - 未修改。你确定你没有设置某种调试模式,强制重新下载所有资源吗?我看到你的请求头包含“Cache-Control: no-cache”... - m_katsifarakis
重新加载后,我只得到了主URL和谷歌字体,其他所有内容都从缓存中以304方式加载。 - David
@David,没错,那是从“(来自内存缓存)”截取的。你的重新加载行为很有趣。所以,当你重新加载global.css文件时,在DevTools网络选项卡的“大小”列中会出现什么? - Garrett
@User23332,没错,这正是我用来强制使用最新CSS的方法。你会从DevTools中注意到,我在CSS(和JS)文件后面添加了一个查询字符串,看起来像:?v=d04f0cc。这里的目标是让浏览器从缓存中加载CSS文件,直到查询字符串发生变化。 - Garrett
显示剩余10条评论
4个回答

4

@Allen发现了问题(Vary头包含cookiecookie在请求之间不断变化),但为了后代,我将展示如何修复Flask的情况。您可以使用Flask的@app.after_request()钩子来确保Flask在到达此行时不添加cookie

@app.after_request
def add_header(response):
    url = request.url
    if ('.css' in url or '.js' in url or '.svg' in url or '.png' in url or
        '.gif' in url) :
        # Flask adds to the header `Vary: cookie` meaning the client should 
        # re-download the asset if the cookie changed.  If you look at the Flask
        # source code that comes next after the below return, it will add 
        # `Vary: cookie` if and only if session.accessed is true.
        session.accessed = False
    return response

1
你应该使用nginx作为前置服务器来处理这些静态文件。http://docs.gunicorn.org/en/stable/deploy.html - Allen
@Allen - 这并不与这个答案互斥。在我的情况下,我有nginx在flask应用程序前面配置为缓存,具有极长的proxy_cache_timeout参数的特定应用程序路径(例如/static)。这样,您可以仅使用内置服务器进行测试,而部署版本仍然可以受益于具有快速前端的优势。 - Fake Name

1

Chrome使用多种类型的缓存。

Blink(Chrome使用的渲染引擎)使用内存缓存和磁盘缓存。它将此缓存用于图像、字体和js文件。只要该类型的文件仍在内存缓存或文件缓存中,它将从那里加载并跳过WebRequest API,这意味着不会向服务器发出调用。

我不知道为什么Blink不缓存css文件,但这就是为什么您会看到对css文件而不是js文件的HTTP请求的原因。

请注意,如果由于某种原因,js文件从内存缓存和磁盘缓存中被清除,您也将看到对js文件的HTTP请求。


谢谢,这很有用,特别是作为挖掘Chromium源代码的起点。奇怪的是,其他网站似乎都正常工作(例如,Stack Overflow的CSS文件在“大小”列中显示“(来自磁盘缓存)”)。 - Garrett

1
您的服务器在请求这些css文件时响应了不同的会话cookie,而您的头部设置了Vary:Cookie,这导致浏览器由于会话cookie的更改而再次发送请求。

谢谢,你说得对!的确,.css请求发送了不同的cookie,而.js请求发送了相同的cookie。不确定为什么会这样,但很容易解决,只需修改Vary头部,将其中的Cookie删除即可。我在此处展示了如何在Flask中实现。 - Garrett

1

请检查您的web.config文件中的编译属性,确认其是否为:

<compilation debug=”true”/> 

每次页面请求时,CSS都会被客户端不断地下载,而不会在浏览器本地缓存。

如果设置为false,则该资源仅在客户端下载一次并在其中缓存。

查看此文章:Chrome不会缓存CSS文件。.js文件可以正常工作


谢谢你的回答!不幸的是,我没有使用链接答案中的IIS,而是Flask(Python)。但实际上,我认为这个问题与服务器技术无关。我的响应头存在问题,可能与Chrome或我的缓存理解有关。 - Garrett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接