【发布时间】:2014-02-01 23:55:39
【问题描述】:
我最近向某些脚本标签添加了 crossorigin 属性,以使我的脚本能够从来自不同子域的脚本中收集错误信息。我在 nginx 中添加了 header 以允许跨域请求。
从那时起,我偶尔会在没有浏览器从服务器请求某些 javascript 文件的情况下加载页面。重新加载页面解决了这个问题,但这种情况已经发生了好几次了。
我认为这与 CORS 有关,但由于它大部分时间都有效,我不知道如何重现它。
以下是我的代码摘录:
Nginx 配置包含针对某个位置的 javascript 文件的这条规则:
add_header 'Access-Control-Allow-Origin' "$http_origin";
我在php页面中的脚本标签:
<script type="text/javascript" src="<?php print "$host/js/$filename?v=$version";?>" crossorigin></script>
当我的页面加载时,我可以在 Firebug 中看到脚本标签是正确的,但在 Firebug Net 选项卡中甚至没有显示请求。通常会显示一个请求,即使它使用文件的缓存版本。
我在这里发现了一个我认为可能相关的问题: all of my browsers are not sending the origin header 但进一步考虑,我认为应该有一个初始请求会失败并且会在 Firebug 中显示。
有人对为什么会发生这种情况有任何理论吗?
编辑: 我为我的 CORS 请求添加了单独的访问日志。 Nginx 添加 CORS 标头的位置中的任何文件也会记录在新的访问日志中。
当页面无法加载 javascript 文件时,Nginx 会记录一个 304 状态(未修改)的请求。这意味着 Nginx 仅在修改后才获得对资源的条件请求,并且 Nginx 发送回 304 而没有其他任何内容。如果缓存的版本没有加载 CORS 标头,则可能无法执行 javascript。
我有一个版本号,我将其附加到脚本标记的 src 中,如上所示。此版本号已更改。那么这不应该导致浏览器重新请求所有这些资源,就好像它们具有不同的文件名一样?我认为浏览器应该将这些视为未缓存的资源。不应该有任何可能导致 304 的请求。这可能是什么原因造成的?
【问题讨论】:
-
也许资源失败并出现一些错误,导致无法发送 cors 标头?服务器错误日志中有任何内容吗?
-
服务器日志中没有错误。它只是一个静态的 javascript 文件,很少会导致服务器端失败。
-
我得到了更多的日志信息并编辑了问题。
-
很奇怪。但是:
That means that Nginx got a conditional request for the resource only if modified, and Nginx sent back the 304 and nothing else.在我看来,这是问题的根源,需要以某种方式进行修改? -
我也是这么想的。但是每当我更改该版本号时,它不应该再检查修改了,因为每个资源都有不同的 url。这些 javascript 文件设置为“expires 30d;”在我的 Nginx 配置中。但是浏览器应该将它作为一个新的 url 来请求,而不是检查缓存的副本。
标签: javascript php nginx cors http-caching