如何使用 angular 应用程序和 java 后端处理 CORS 错误?
How to handle CORS error with an angular app and a java backend?
我有一个 angular 应用程序试图将 ajax 请求发送到 java 后端(API 使用 Jersey 构建)。
这是客户请求:
let settings = {
"url": "http://localhost:8080/simulator/config",
"method": "POST",
"timeout": 0,
"headers": {
"Content-Type": "application/json"
},
"data": JSON.stringify({
"fromDate": fromDate,
"tsIntervalTag": tsIntervalTag,
"tsIntervalDevice": tsIntervalDevice,
"devicePerMinute": devicePerMinute,
"tagPerMinute": tagPerMinute,
"quantityOfTags": quantityOfTags,
"quantityOfDevices": quantityOfDevices
}),
};
$.ajax(settings).done(function (response) {
console.log(response);
});
这里是 java 后端请求处理程序:
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response postIt(String body) {
try {
//do stuff
return Response.ok(body, MediaType.APPLICATION_JSON).header("Access-Control-Allow-Origin", "*").build();
} catch (Exception e) {
return Response.serverError().entity(e).header("Access-Control-Allow-Origin", "*").build();
}
}
如您所见,几乎所有关于CORS状态的答案,Access-Control-Allow-Origin
header设置为*
通配符,所以根据我的理解,响应应该返回到浏览器。
但是浏览器控制台returns如下:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at http://localhost:8080/simulator/config.
(Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at http://localhost:8080/simulator/config.
(Reason: CORS request did not succeed).
那我错过了什么?
好像和Jersey一样,还是用filters来设置CORS比较好。 (至少在我的场景中,应该从任何地方(到目前为止)接受所有请求)。
所以我创建了以下 class(在它自己的 java 文件中):
package com.example;
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.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;
@Provider
public class CORSFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
throws IOException {
System.out.println("FILTER HERE ");
MultivaluedMap<String, Object> headers = responseContext.getHeaders();
headers.add("Access-Control-Allow-Origin", "*"); // Allow Access from everywhere
headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
headers.add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
}
}
基本上就是这样。所有请求都将通过此并获得正确的 headers。我不知道为什么直接在方法中设置 headers 不起作用。
我有一个 angular 应用程序试图将 ajax 请求发送到 java 后端(API 使用 Jersey 构建)。
这是客户请求:
let settings = {
"url": "http://localhost:8080/simulator/config",
"method": "POST",
"timeout": 0,
"headers": {
"Content-Type": "application/json"
},
"data": JSON.stringify({
"fromDate": fromDate,
"tsIntervalTag": tsIntervalTag,
"tsIntervalDevice": tsIntervalDevice,
"devicePerMinute": devicePerMinute,
"tagPerMinute": tagPerMinute,
"quantityOfTags": quantityOfTags,
"quantityOfDevices": quantityOfDevices
}),
};
$.ajax(settings).done(function (response) {
console.log(response);
});
这里是 java 后端请求处理程序:
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response postIt(String body) {
try {
//do stuff
return Response.ok(body, MediaType.APPLICATION_JSON).header("Access-Control-Allow-Origin", "*").build();
} catch (Exception e) {
return Response.serverError().entity(e).header("Access-Control-Allow-Origin", "*").build();
}
}
如您所见,几乎所有关于CORS状态的答案,Access-Control-Allow-Origin
header设置为*
通配符,所以根据我的理解,响应应该返回到浏览器。
但是浏览器控制台returns如下:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/simulator/config. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/simulator/config. (Reason: CORS request did not succeed).
那我错过了什么?
好像和Jersey一样,还是用filters来设置CORS比较好。 (至少在我的场景中,应该从任何地方(到目前为止)接受所有请求)。
所以我创建了以下 class(在它自己的 java 文件中):
package com.example;
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.core.MultivaluedMap;
import javax.ws.rs.ext.Provider;
@Provider
public class CORSFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
throws IOException {
System.out.println("FILTER HERE ");
MultivaluedMap<String, Object> headers = responseContext.getHeaders();
headers.add("Access-Control-Allow-Origin", "*"); // Allow Access from everywhere
headers.add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
headers.add("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
}
}
基本上就是这样。所有请求都将通过此并获得正确的 headers。我不知道为什么直接在方法中设置 headers 不起作用。