环境 Tomcat Server托管webservice应用程序。 网站是使用SpringMVC和AngularJS构建的。
核心问题: REST GET触发OPTIONS请求,该请求失败。 有问题的GET返回应用程序/ JSON响应。 最初,我收到了错误:
"无法加载资源:服务器响应状态为403(禁止)
无法加载http://myServer:8084/wsPRDE/navbar/getnavbartxt:对预检请求的响应未通过访问控制检查:否' Access-Control-Allow-Origin'标头出现在请求的资源上。起源' http://myServer:8080'因此不允许访问。响应的HTTP状态代码为403。"
在此问题出现之前,我们所做的只是在控制器中使用@CrossOrigin。然后设置httpd.conf来添加这些标头。这对于从站点检索的所有脚本(具有讽刺意味的不是CORS)而不是实际的CORS响应。当我确保在响应中返回Access-Control-Allow-Origin,Allow-Methods和Allow-Headers时,通过将CORSFilter编码到Web服务中,错误更改为:
"选项http://myServer:8084/wsPOFA/navbar/getnavbartxt 403(禁止) 无法加载http://myServer:8084/wsPOFA/navbar/getnavbartxt:预检的响应包含无效的HTTP状态代码403."
背景 以相当随机的方式检测到错误。 我的流程管理同事有一个Windows 10更新。 自上述更新以来,整个Web服务失败,因为无法访问。从站点本身到Web应用程序(相同地址,不同端口)的任何请求都会失败。我的上级(我是实习生)然后发现在Chrome和IE中(当使用服务器别名时,而不是在使用"普通" URL时)在没有Windows 10更新的情况下具有相同的问题。在更新之前(或使用具有普通URL的IE),GET似乎不会触发OPTIONS请求。
进一步尝试在此之后,我尝试展开Allow-Headers以包含GET请求/响应中的所有字段。我还将OPTIONS请求中的Origin与Origins的白名单进行比较,将OPTIONS响应Allow-Origin标头值设置为请求Origin值(如果它们匹配)。
因此,起源匹配并且请求/响应中的所有标头都被设置为允许。到目前为止,我花了3天时间阅读CORS并在网上寻找解决方案。大多数解决方案都提到了我已实现的CORS过滤器,然后完全清除标头有大量的脏处理方法,总是对OPTIONS请求响应200 OK。但他们看起来很肮脏"的解决方案。
有人能指出我正确的方向吗?我应该考虑向我的Spring控制器添加与CORS相关的代码吗?向AngularJS构建httpRequests的委托是我问题的关键吗?还是我完全在想错误的方向?
目前,我的请求/响应标头如下所示:
答案 0 :(得分:0)
这个问题被低估了,可能是因为当我决定寻求帮助时,我并没有完全清楚。无论如何,我今天设法解决了这个问题。当我发布问题时,我已经在应用程序级别创建了自定义CORS过滤器。如果设置了Allow-Origin和Allow-Methods字段并且仅对非选项请求应用chain.doFilter(),则更改此过滤器以手动将“状态代码”设置为“200”以解决此问题。我不确定它是否是理想/安全的解决方案。但它的确有效。您可以在下面找到所使用的完整解决方案。
的web.xml:
<filter>
<filter-name>SimpleCORSFilter</filter-name>
<filter-class>com.ofis.webservice.CORS.SimpleCORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SimpleCORSFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
过滤类:
package com.ofis.webservice.CORS;
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SimpleCORSFilter implements Filter {
ArrayList<String> AllowedOrigins;
ArrayList<String> AllowedMethods;
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
if (request.getMethod().equals("OPTIONS")) {
String reqOrigin;
reqOrigin = request.getHeader("Origin");
for (String origin : AllowedOrigins) {
if (origin.equals(reqOrigin)) {
response.setHeader("Access-Control-Allow-Origin", reqOrigin);
break;
}
}
String reqMethod;
reqMethod = request.getHeader("Access-Control-Request-Method");
for (String method : AllowedMethods) {
if (method.equals(reqMethod)) {
response.setHeader("Access-Control-Allow-Method", reqMethod);
}
}
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers", "cache-control,if-modified-since,pragma,Content-Type");
//Checks if Allow-Method and Allow-Origin got set. 200 OK if both are set.
if(!response.getHeader("Access-Control-Allow-Method").equals("") && !response.getHeader("Access-Control-Allow-Origin").equals("")){
response.setStatus(200);
}
} else {
chain.doFilter(req, res);
}