我遇到一个奇怪的问题:CORS,XMLHttpRequest和JAX-RS。 我们想从 mysite.com
service.myapi.com 对我们的REST-API(Java,JAX-RS)进行ajax调用。当我们使用标题Accept: 'application/json'
$.ajax({
type: 'POST',
url: 'https://service.myapi.com/rest/machine/metadata',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Session-Token': myToken
},
data: JSON.stringify({
'machine-number': 1
})
});
从浏览器中获取以下消息:
阻止跨源请求:同源策略禁止在https://service.myapi.com/rest/machine/metadata读取远程资源。 (原因:缺少CORS标题'Access-Control-Allow-Origin'。)
但是,如果我更改为Accept: 'application/xml'
,则按预期工作(!)。
这就是我在服务器上查看的方式
添加CORS标头的过滤器
private static final String ALLOW_HEADERS = createAllowHeaders();
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
try {
chain.doFilter(request, response);
} catch(Exception e) {
response.setStatus(500);
} finally {
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Expose-Headers","Session-Token");
response.addHeader("Access-Control-Allow-Headers", ALLOW_HEADERS);
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
}
}
private static String createAllowHeaders() {
return new StringJoiner(", ")
.add("Access-Control-Allow-Headers")
.add("X-Requested-With")
.add("Access-Control-Request-Method")
.add("Access-Control-Request-Headers")
.add("origin")
.add("content-type")
.add("accept")
.add("authorization")
.add("Session-Token")
.toString();
}
使用JAX-RS注释处理请求的方法
@Path("/metadata")
@POST
@Consumes({ APPLICATION_XML, APPLICATION_JSON })
@Produces({ APPLICATION_XML, APPLICATION_JSON })
public Response getMetadata(@Context HttpServletRequest req, MetadataRequest m) {
//...
}
我不知道为什么在使用Accept: 'application/json'
时它不起作用。在Chrome和Firefox中测试过。在两种浏览器中获得相同的结果。