在background.js
中,我的浏览器扩展定期获取发布在GitHub公共存储库中的JSON文件。
现在我希望它对GitHub和它的带宽限制更好,并且只有在上次更新后修改过的情况下才能再次提取文件:
url='https://raw.githubusercontent.com/LearnWebCode/json-example/master/pets-data.json';
fetch(url, {
headers: {'If-Modified-Since': 'Wed, 15 Aug 2022 18:30:00 GMT'}})
.then(response => response.json())
.then(json => console.log('Loaded: ', json));
但是我收到CORS错误,我不知道如何处理:
Access to fetch at
'https://raw.githubusercontent.com/LearnWebCode/json-example/master/pets-data.json'
from origin 'chrome-extension://...'
has been blocked by CORS policy:
Response to preflight request doesn't pass access control check:
It does not have HTTP ok status.
添加其他标题的任意组合都没有区别:
'Content-Type': 'text/plain;charset=UTF-8'
'Accept': 'application/vnd.github.v3.raw'
'User-Agent': 'my_github_username/my_github_repository (Chrome 104.0.5112.79)'
使用GitHub Pages作为访问该文件的替代方式也没有。
更新:我轻松消除了在manifest.json
中将raw.githubusercontent.com
添加到host_permissions
的CORS错误(感谢@wOxxOm
(。然而,现在If-Modified-Since
似乎并没有像我预期的那样影响服务器行为,请参阅后续问题的详细信息。
因为您的请求包含一个If-Modified-Since
头,所以浏览器会触发CORS预飞行。然而,尽管资源使用Access-Control-Allow-Origin: *
响应GET
请求,但它似乎不支持预飞:如果你试图欺骗预飞请求,它总是(根据我的测试(以403状态回复,这足以让CORS预飞失败。
资源确实以ETag
标头进行响应。一种方法是首先发送简单HEAD
请求,读取响应的ETag
标头的值,然后有条件地发送GET
请求。不幸的是,由于ETag
不是CORS安全列出的响应标头名称,并且响应不包含任何Access-Control-Expose-Headers
标头,因此浏览器不会将响应的ETag
标头暴露给JavaScript。非常难过。
除了迫使GitHub在https://raw.githubusercontent.com
上添加对CORS预飞的支持外,一个可行但令人讨厌的替代方案是将您的原始GET
请求(包含If-Modified-Since
标头(代理到您控制的服务器,这将不受同源策略的约束。