使用HTML5 fetch API允许Access-Control-Allow-Origin标头

iNi*_*kkz 54 html api url fetch-api

我正在使用HTML5 fetch API.

var request = new Request('https://davidwalsh.name/demo/arsenal.json');

fetch(request).then(function(response) {
    // Convert to JSON
    return response.json();
}).then(function(j) {
    // Yay, `j` is a JavaScript object
    console.log(JSON.stringify(j));
}).catch(function(error) {
    console.log('Request failed', error)
});
Run Code Online (Sandbox Code Playgroud)

我能够使用普通的json但无法获取上述api url的数据.它抛出错误:

Fetch API无法加载https://davidwalsh.name/demo/arsenal.json.请求的资源上不存在"Access-Control-Allow-Origin"标头.原产地" :HTTP //本地主机,因此"是不允许访问.如果不透明响应满足您的需求,请将请求的模式设置为"no-cors"以获取禁用CORS的资源.

Dav*_*les 56

像epascarello所说,托管资源的服务器需要启用CORS.您可以在客户端(也可能是您正在考虑的)设置获取CORS的模式(尽管这是我认为的默认设置):

fetch(request, {mode: 'cors'});
Run Code Online (Sandbox Code Playgroud)

但是,这仍然需要服务器启用CORS,并允许您的域请求资源.

查看CORS文档,这个非常棒的Udacity视频解释了同源策略.

您也可以在客户端使用no-cors模式,但这只会给您一个不透明的响应(您无法读取正文,但响应仍然可以由服务工作者缓存或由某些API使用,例如<img>) :

fetch(request, {mode: 'no-cors'})
.then(function(response) {
  console.log(response); 
}).catch(function(error) {  
  console.log('Request failed', error)  
});
Run Code Online (Sandbox Code Playgroud)

  • 您能否详细说明“但是,这仍然需要服务器也启用 CORS,并允许您的域请求资源。”?我一直没有成功地寻找这样做的说明。 (2认同)
  • @jayscript的整个过程如下所示:在客户端上,使用javascript提出了跨源请求。对于fetch API,“ cors”模式会告知浏览器可以进行此请求。如果您使用的是“ no-cors”模式,则浏览器将停止该请求,因为它与您的应用程序无关。服务器将收到请求并做出响应。*浏览器*确认响应具有适当的CORS标头,如果是,则允许读取响应。如果标题不存在,浏览器将抛出错误。 (2认同)
  • 谢谢!这有助于我理解,当API服务器不包含任何标头时,无法从具有不同来源的API服务器获取数据.在我正在处理的特定情况下,我可以访问API服务器代码并且能够自己添加标题,这启用了提取功能. (2认同)

小智 19

这对我有用:

npm install -g local-cors-proxy
Run Code Online (Sandbox Code Playgroud)

我们要请求的具有 CORS 问题的 API 端点:

https://www.yourdomain.com/test/list
Run Code Online (Sandbox Code Playgroud)

启动代理:

lcp --proxyUrl https://www.yourdomain.com

 Proxy Active 

 Proxy Url: http://www.yourdomain.com:28080
 Proxy Partial: proxy
 PORT: 8010
Run Code Online (Sandbox Code Playgroud)

然后在您的客户端代码中,新的 API 端点:

http://localhost:8010/proxy/test/list
Run Code Online (Sandbox Code Playgroud)

最终结果将是对https://www.yourdomain.ie/test/list的请求,而没有 CORS 问题!


Mat*_*ttG 9

我知道这是一篇较旧的帖子,但我发现解决此错误的方法是使用我服务器的 IP 地址,而不是在我的提取请求中使用域名。例如:

#(original) var request = new Request('https://davidwalsh.name/demo/arsenal.json');
#use IP instead
var request = new Request('https://0.0.0.0/demo/arsenal.json');

fetch(request).then(function(response) {
    // Convert to JSON
    return response.json();
}).then(function(j) {
    // Yay, `j` is a JavaScript object
    console.log(JSON.stringify(j));
}).catch(function(error) {
    console.log('Request failed', error)
});
Run Code Online (Sandbox Code Playgroud)


sms*_*ash 7

I had my front code running in http://localhost:3000 and my API(Backend code) running at http://localhost:5000

Was using fetch API to call the API. Initially it was throwing "cors" error. Then added this below code in my Backend API code, allowing origin and header from anywhere.

let allowCrossDomain = function(req, res, next) {
  res.header('Access-Control-Allow-Origin', "*");
  res.header('Access-Control-Allow-Headers', "*");
  next();
}
app.use(allowCrossDomain);
Run Code Online (Sandbox Code Playgroud)

However you should restrict the you origins in case of other environments like stage, prod.

  • 这是针对本地设置的。例如,快速拍一张照片。是的,如果其他可部署环境也是如此,则存在安全风险。对于本地,我觉得不是。“但是,在舞台、产品等其他环境中,您应该限制您的来源” (6认同)
  • 这是一个可怕的答案。这是一个巨大的安全问题。如果您正在阅读本文,请不要这样做。 (2认同)
  • @DapoMichaels 将值设置为您想要允许的实际严格值。不只是“*” (2认同)