即使存在所有 CORS 标头,也存在跨源资源共享问题

Posted

技术标签:

【中文标题】即使存在所有 CORS 标头,也存在跨源资源共享问题【英文标题】:Cross Origin Resource sharing issue even when all the CORS headers are present 【发布时间】:2015-06-18 12:16:59 【问题描述】:

即使我在我的服务响应中附加了以下提供的 CORS 标头

resp.setContentType("application/json");
resp.addHeader("Access-Control-Allow-Origin", "*");
resp.addHeader("Access-Control-Allow-Credentials", "true");
resp.addHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
resp.addHeader("Access-Control-Allow-Headers", "Origin,accept,content-type");
resp.flushBuffer();

在尝试通过我的 AngularJS 前端访问服务中的一些 POST Web 方法时,我仍然在控制台中遇到错误。

XMLHttpRequest cannot load http://192.***.*.***:8080/abc/def/search/vehicleManufacturer. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://192.***.*.***:8085' is therefore not allowed access.

然而,在同一个类中,一些没有任何有效负载的 POST 方法可以完美响应。有什么建议吗?

编辑--------->

下面是我调用 web 方法的 AngularJS 客户端屏幕代码:-

getVehicleModel : function(searchData,$scope)
     $http(
         method:'POST',
         url:'http://192.169.*.***:8085/abc/def/search/vehicleModel',
         dataType:'jsonp',
         data:searchData

     ).
     success(function(data)
         console.log("vehicle model")
         $scope.vehicleModel = data.Response;

     );


,

【问题讨论】:

您是否检查了您在代码中添加的响应标头是否实际上是响应 DevTools 中的 ajax 调用?您使用的是任何框架还是只是普通的 servlet? 不,对于其中 m 出现错误的 Web 方法,它会作为方法的 OPTIONS 出现,并且其中缺少响应标头。 它是普通的原始 servlet。 删除这个“resp.flushBuffer();”一次检查 看看这个***.com/questions/21188956/… 【参考方案1】:

我认为这里的问题是 CORS 中的 Preflighted Requests。

来自 Mozilla 文档,

与简单的请求(上面讨论过)不同,“预检”请求首先 通过 OPTIONS 方法向资源上的资源发送 HTTP 请求 其他域,以判断实际请求是否安全 发送。跨站点请求是这样预检的,因为它们可能 对用户数据有影响。特别是,请求是 预检如果:

它使用 GET、HEAD 或 POST 以外的方法。此外,如果 POST 用于发送 Content-Type 不是

的请求数据 application/x-www-form-urlencoded, 多部分/表单数据 文本/纯文本

例如如果 POST 请求使用 application/xml 或 text/xml 将 XML 有效负载发送到服务器,则请求被预检。

它在请求中设置自定义标头(例如,请求使用诸如 X-PINGOTHER 之类的标头)

如上所述,即使您发出一个简单的 POST 请求,您的请求中的 Content-Type 也是 application/json,这与上面提到的 3 种类型不同,因此它被视为 Preflight 请求和 OPTIONS 请求在您的实际 POST 请求之前触发。

您可以通过在您的 servlet 中实现 doOptions 来解决此问题,只需在其中添加标头即可:)

【讨论】:

很高兴能帮上忙 :) 谢谢,HttpServlet.doOptions 成功了。【参考方案2】:

由于您发送跨域 ajax 请求并使用此 GET 请求指定 Authorization 标头,因此发生预检 (OPTIONS)。

另外(这不会导致问题)我建议删除 contentType 选项。这在 GET 请求的上下文中没有意义。 GET 请求不应包含任何内容。所有数据都应包含在查询字符串或可能的标题中。

授权标头不会与 OPTIONS 一起发送。您必须在服务器端确认它,然后浏览器将发送底层 GET。在https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS 上阅读有关 CORS 的更多信息。

【讨论】:

如果使用POST向服务器发送数据,HTTP POST请求发送给服务器的数据的Content-Type是application/x-www-form-urlencoded, multipart/之一表单数据,或文本/纯文本 我不认为 HTTP 仅限于 POST 多部分或 x-www-form-urlencoded。 Content-Type Header 独立于 HTTP POST 方法(您可以填写适合您的 MIME 类型)。

以上是关于即使存在所有 CORS 标头,也存在跨源资源共享问题的主要内容,如果未能解决你的问题,请参考以下文章

即使存在标头,CORS 也会失败

错误:不存在“Access-Control-Allow-Origin”标头。即使我添加了它

请求的资源上不存在“Access-Control-Allow-Origin”标头。 ExpressJs

即使使用 Access-Control-Allow-Origin 也被 CORS 阻止的 API 调用:* 存在于标头中

访问被 CORS 阻止的 XMLHttpRequest,请求的资源上不存在“Access-Control-Allow-Origin”标头,仅用于 PUT 和 DELETE API

使用 PHP 的 CORS(跨源资源共享)