我在我的apache网络服务器上启用了Access-Control-Allow-Origin。我可以在第一次加载时加载所有请求。但是,随后加载/刷新页面会使一半的请求失败,并留下错误
XMLHttpRequest cannot load http://***. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
在Chrome开发者工具的“网络”标签下,启用"禁用缓存"删除此错误。
我使用AngularJS $ http来调用我的请求,我已将缓存选项更改为true / false但这种异常仍然存在。为了您的信息,我也使用角度缓存模块,https://github.com/jmdobry/angular-cache,我也试过启用/禁用它,但无济于事。
以下是请求标头的副本:
GET ***Valid_Url_With_Parameters** HTTP/1.1
Host: ********
Connection: keep-alive
Accept: application/json, text/plain, */*
Origin: http://localhost:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36
Referer: http://localhost:3000/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
我有两种不同类型的响应标头,其中包含针对失败请求的不同HTTP状态代码。
HTTP/1.1 200 OK
Content-Length: 564121
Content-Type: application/json
Server: Apache/2.2.15 (CentOS)
Vary: Accept
Last-Modified: Fri, 16 Sep 2016 12:41:41 GMT
Connection: keep-alive
Date: Fri, 16 Sep 2016 12:43:44 GMT
HTTP/1.1 206 Partial Content
Content-Type: application/json
Server: Apache/2.2.15 (CentOS)
Vary: Accept
Last-Modified: Fri, 16 Sep 2016 13:39:05 GMT
Content-Range: bytes 29200-29200/785592
Content-Length: 1
Connection: keep-alive
Date: Fri, 16 Sep 2016 14:20:48 GMT
这似乎与缓存有关。页面第一次加载时,所有请求都具有正确的访问控制标头。后续刷新/重新加载会删除此标头。如何继续使用缓存并保留访问控制标题?
编辑:
只是为了补充一下,我尝试使用Safari,出现了同样的异常。它在第一次尝试时加载,但后续加载将抛出无访问控制允许原始错误。但是,这次,Safari中的响应标题显示为空白。
编辑2:
Firefox中也出现异常,但Opera Beta版本40.0.2308.52中没有。我开始怀疑这是否是浏览器的原因。 Access-Control-Allow-Origin标头也存在。
Opera中的响应标头
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Date: Sat, 17 Sep 2016 06:56:53 GMT
Server: Apache/2.2.15 (CentOS)
Vary: Accept
Transfer-Encoding: chunked
编辑3: 我想补充一点,我所提取的请求是大量数据。我拉了最近7天的数据历史,大约有20个JSON文件,每个文件的范围从500KB到1000KB。我注意到,当我更改查询参数以引入较小的数据历史时,不会发生此错误。
非常感谢任何帮助。
答案 0 :(得分:0)
我发现的一项工作是在服务器上动态生成javascript文件,作为页面中包含的资源。这并不需要AJAX,它被CORS阻止并且可以被缓存。
答案 1 :(得分:0)
我建议您在浏览器中添加chrome扩展名
Allow-Control-Allow-Origin:*
答案 2 :(得分:0)
在“Access-Control-Allow-Origin”标头中返回特定值时,我们在 Chrome 中遇到了同样的问题。我们还通过在响应标头中包含 Vary: Origin
来解决该问题。
Chrome 似乎将响应标头(包括“Access-Control-Allow-Origin”)视为缓存响应的一部分。因此,如果它从不同的来源请求相同的文件,则缓存中的标头将不匹配。但是,如果您包含 Vary: Origin
,它会让 Chrome 知道响应(在我们的例子中只有这个标头)会根据请求的来源而有所不同。
这page on MDN解释了:
<块引用>如果服务器发送带有 Access-Control-Allow-Origin 的响应 明确来源的值(而不是“*”通配符),然后 响应还应该包含一个带有值的 Vary 响应头 Origin — 向浏览器表明服务器响应可能不同 基于 Origin 请求标头的值。