我使用Spring 3和Resteasy设置了一个Web应用程序;由于我的资源需要身份验证,因此我不允许使用*作为Access-Control-Allow-Origin。 所以我配置了
org.jboss.resteasy.plugins.interceptors.CorsFilter
使用正确的原始域名。 这适用于桌面客户端(Paw for Mac Os等),但不适用于浏览器(Chrome);问题是响应包含Access-Control-Allow-Origin的双精度值,即我配置的那个和'*'。
CorsFilter不应该受到责备,因为即使你配置了多个原点,它总是只为标题添加一个值,即请求所要求的值。
我根本不知道谁会把那个额外的(和错误的)标题,任何想法放在我能找到的地方? 请注意,双标头出现在GET请求上,但不出现在OPTIONS请求上。
答案 0 :(得分:1)
我不确定您的双头标头来自哪里,但您是否尝试使用自定义过滤器? 例如:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter {
public SimpleCorsFilter() {
}
@Override
public void doFilter(ServletRequest req,
ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Authorization, Content-Type");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void destroy() {
}
}
答案 1 :(得分:0)
我终于发现类路径中有一个专有的MessageBodyWriterInterceptor,它执行了错误的添加标头;现在,我删除它。 我学到的一件事是,如果只有在有一个正在写入的主体时才会发生某些事情,那么一个好的起点肯定是渲染管道
答案 2 :(得分:0)
我尝试了以下操作,它起到了魅力作用:
首先,在web.xml中注册CorsFilter提供程序类:
<context-param>
<param-name>resteasy.providers</param-name>
<param-value>org.jboss.resteasy.plugins.interceptors.CorsFilter</param-value>
</context-param>
通过这样做,您的服务器已经启用了处理CORS请求,但是,您需要添加一些允许的来源才能使其正常工作,因此,您应该可以访问由RestEasy创建的CorsFilter实例,然后添加所有您希望授予访问权限的URL,或者如果您希望授予对任何内容的访问权限,则添加*。
在这方面,如果您正在使用RestEasy Spring Integration,则需要通过将其自动装入代码中来获取org.jboss.resteasy.spi.ResteasyProviderFactory
类的实例:
@Autowired
private ResteasyProviderFactory processor;
然后使用注释为@PostConstruct
的设置方法从ResteasyProviderFactory
获取CorsFilter的实例,如下面的代码段所示:
@PostConstruct
public void setUp() {
ContainerRequestFilter[] requestFilters = processor.getContainerRequestFilterRegistry().preMatch();
CorsFilter filter = (CorsFilter) Iterables.getLast(Iterables.filter(Arrays.asList(requestFilters), Predicates.instanceOf(CorsFilter.class)));
filter.getAllowedOrigins().add("*");
}
P.S。:我正在使用这个框架:
我希望它有所帮助!
答案 3 :(得分:0)
对于那些像我这样没有使用应用程序启动程序但只使用Spring + Reasteasy的人。
只需添加web.xml:
<context-param>
<param-name>resteasy.providers</param-name>
<param-value>package.to.your.cors.CORSFilter</param-value>
</context-param>
并创建类似
的Java类CORSFilterpackage package.to.your.cors;
import java.io.IOException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
@Provider
public class CORSFilter implements ContainerResponseFilter {
@Override
public void filter(final ContainerRequestContext requestContext,
final ContainerResponseContext cres) throws IOException {
cres.getHeaders().add("Access-Control-Allow-Origin", "*");
cres.getHeaders().add("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
cres.getHeaders().add("Access-Control-Allow-Headers", "X-Auth-Token, Content-Type");
cres.getHeaders().add("Access-Control-Max-Age", "4800");
}
}
它就像一个魅力。
PS:受到筒嘴头答案的启发,但我无法评论他的答案,以添加我的详细信息。