无法设置“Access-Control-Allow-Origin”标头

Posted

技术标签:

【中文标题】无法设置“Access-Control-Allow-Origin”标头【英文标题】:unable to set 'Access-Control-Allow-Origin' header 【发布时间】:2018-01-24 12:39:06 【问题描述】:

我需要从我的 react 应用程序远程访问我的 web api。在服务器端,我做了以下允许跨域通信:

import javax.ws.rs.core.Response;
import com.mypackage.ResponseDto;

@Override
public Response fetch(String id, String env) throws ServiceException
 
     ResponseDto res = new ResponseDto();
     res = updateResp(id, env); // not important

     return Response.ok().header("Access-Control-Allow-Origin","*").entity(res).build();

当我从邮递员那里检查时,我可以看到 cors 标头正确设置如下:

access-control-allow-origin →*
content-type →application/json
date →Wed, 16 Aug 2017 11:07:16 GMT
server →web
transfer-encoding →chunked

但是当我从 react 应用程序访问同一个端点时,浏览器开始抱怨以下错误:

Fetch API 无法加载 http://myservices.com/myservice-app/services/。回应 预检请求未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“http://localhost:3000” 使用权。如果不透明的响应满足您的需求,请设置请求的 模式为“no-cors”以获取禁用 CORS 的资源

知道这里发生了什么吗?

编辑#1 以下更改是否仍然看到相同的错误:

return Response.ok()
            .header("Access-Control-Allow-Origin", "*")
            .header("Access-Control-Allow-Methods", "POST, GET, PUT, UPDATE, OPTIONS")
            .header("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With")
            .entity(response).build();

【问题讨论】:

需要将标头添加到对 OPTIONS 请求的响应中(这是浏览器将作为此“预检”请求发送的内容),而不是(仅)GET 或 POST。也许这就是问题所在? 服务器收到OPTIONS请求时的响应如何,这是在下一个请求之前发送的 "No 'Access-Control-Allow-Origin' header is present on the requested resource"的可能重复 如果您仍然只是在非 OPTIONS 请求上设置这些标头,我认为编辑不会真正有帮助。从您发布的调用 fetch 的代码来看,这并不明显。阅读 this 答案,了解有关在您的环境中启用 CORS 的一些有用信息。 就邮递员的检查而言,您需要通过发送 OPTIONS 请求进行测试,因为您的浏览器在发出您要发送的实际请求之前正在执行 CORS 预检 OPTIONS。您还需要确保在测试时发送 Origin 请求标头,并且您要发送 Content-Type: application/json 请求标头。我不知道如何用 postman 做这些的细节,但是使用 curl,它看起来像这样:curl -X OPTIONS -i -H "Origin: http://localhost:3000/" -H "Content-Type: application/json" http://myservices.com/myservice-app/services/ 【参考方案1】:

我对您使用的任何 Java 库都没有经验,但这样的东西必须有效:

@Override
public Response options() throws ServiceException
 
     ResponseDto res = new ResponseDto();

     return Response.ok().header("Access-Control-Allow-Origin","*").entity(res).build();

如果库像我认为的那样工作,这将在您发送到服务器的每个 OPTIONS 请求上发送一个 200 OK,标头为 Access-Control-Allow-Origin = *。这才是你应该追求的目标。

【讨论】:

这仅在 api 不涉及任何自定义标头(如来源、内容类型、接受、授权)时才有效,对于带有一些自定义标头的 api 调用,这将不起作用

以上是关于无法设置“Access-Control-Allow-Origin”标头的主要内容,如果未能解决你的问题,请参考以下文章

通过 Axios 从 Javascript 代码发布到 .net Web Api 时,Access-Control-Allow Headers CORS 错误

XMLHttpRequest 无法加载资源

使用 CORS 的 Javascript 和 angularjs

ABP PUTDELETE请求错误405.0 - Method Not Allowed 因为使用了无效方法(HTTP 谓词) 引发客户端错误 No 'Access-Control-Allow

跨域socket.io 30秒后中断

Express 中间件未设置 CORS 标头