由于 CORS,HTTP post 请求失败
Failed HTTP post request because of CORS
我没能拿到我的申请 运行。我整天都在阅读这篇文章,尝试了很多东西,但最终没有任何效果。在上次尝试中,我尝试了这个 link。我将 java 后端作为 RESTful Web 服务,没有任何其他框架,如 Jersey 或 RESTeasy,只是纯粹的 java。我有我的登录 POST 方法:
@POST
@Path("login")
@Produces(value = "application/json")
public Response login() {
AccountAuthentificator authentificator = AccountAuthentificator.getInstance();
Status status = Response.Status.OK;
String credentialValue = getHeaderValue(AccountAuthentificator.AUTH_CREDENTIALS);
if (credentialValue == null) {
status = Response.Status.FORBIDDEN;
return WebServiceUtil.createResponse(status, "Missing account credentials in header.");
}
try {
LoginResponse res = authentificator.login(credentialValue);
return WebServiceUtil.createResponse(status, res);
} catch (AccessControlException e) {
status = Response.Status.FORBIDDEN;
return WebServiceUtil.createResponse(status,
"User does not exist. Please verify your user name and password.");
}
}
WebServiceUtil.createResponse 方法基本上添加了必要的 headers,如您所见:
public static Response createResponse(Status status, Object responseContent) {
ResponseBuilder resBuilder = Response.status(status.getStatusCode());
resBuilder.header("Access-Control-Allow-Origin", "*");
resBuilder.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
resBuilder.header("Access-Control-Allow-Credentials", "true");
resBuilder.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
resBuilder.allow("OPTIONS");
resBuilder.entity(getJSONAsString(responseContent));
return resBuilder.build();
}
我也看到有人用另一种方法。它带有过滤器,例如 example。我还想知道我的实现是否与此不同以及预检定义的确切位置 - 在我的实现中它是 .allow("OPTIONS") 这样做的,但你可以纠正我我错了。
然后我有我的 Web 应用程序,我在其中调用此 POST 方法。我为此使用 AngularJS。在我的 AuthenticateController 控制器中,我有登录方法,它在登录表单中提交时调用。实现如下所示:
function Login(username, password) {
// CreateLoginHeader creates the authorization token through the login values username and password
var authdata = CreateLoginHeader(username, password);
var config = {
withCredentials: true,
headers: { 'Authorization': authdata }
};
$http.post('http://XXXX', config).then(SuccessLogin, ErrorLogin);
}
有人知道这里出了什么问题吗?通过 chrome 开发人员工具,我可以看到我得到了错误 "XMLHttpRequest cannot load 'placeholder-server-URL'. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'placeholder-client-URL' is therefore not allowed access."。
我是否应该在客户端调用我的后端时添加这两个 header 值:
- Access-Control-Request-Method
- Access-Control-Request-Headers
选项请求未由 login
处理,因此未调用 createResponse
。
看看:https://blogs.oracle.com/theaquarium/entry/supporting_cors_in_jax_rs (you should implement a javax.ws.rs.container.ContainerResponseFilter
, see How to handle CORS using JAX-RS with Jersey)
此处代码的另一种可能性(但如果您开发 'real' 应用程序则不是):将 @javax.ws.rs.OPTIONS
添加到您的方法中,就像您对 @javax.ws.rs.POST
.
所做的那样
我没能拿到我的申请 运行。我整天都在阅读这篇文章,尝试了很多东西,但最终没有任何效果。在上次尝试中,我尝试了这个 link。我将 java 后端作为 RESTful Web 服务,没有任何其他框架,如 Jersey 或 RESTeasy,只是纯粹的 java。我有我的登录 POST 方法:
@POST
@Path("login")
@Produces(value = "application/json")
public Response login() {
AccountAuthentificator authentificator = AccountAuthentificator.getInstance();
Status status = Response.Status.OK;
String credentialValue = getHeaderValue(AccountAuthentificator.AUTH_CREDENTIALS);
if (credentialValue == null) {
status = Response.Status.FORBIDDEN;
return WebServiceUtil.createResponse(status, "Missing account credentials in header.");
}
try {
LoginResponse res = authentificator.login(credentialValue);
return WebServiceUtil.createResponse(status, res);
} catch (AccessControlException e) {
status = Response.Status.FORBIDDEN;
return WebServiceUtil.createResponse(status,
"User does not exist. Please verify your user name and password.");
}
}
WebServiceUtil.createResponse 方法基本上添加了必要的 headers,如您所见:
public static Response createResponse(Status status, Object responseContent) {
ResponseBuilder resBuilder = Response.status(status.getStatusCode());
resBuilder.header("Access-Control-Allow-Origin", "*");
resBuilder.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
resBuilder.header("Access-Control-Allow-Credentials", "true");
resBuilder.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
resBuilder.allow("OPTIONS");
resBuilder.entity(getJSONAsString(responseContent));
return resBuilder.build();
}
我也看到有人用另一种方法。它带有过滤器,例如 example。我还想知道我的实现是否与此不同以及预检定义的确切位置 - 在我的实现中它是 .allow("OPTIONS") 这样做的,但你可以纠正我我错了。
然后我有我的 Web 应用程序,我在其中调用此 POST 方法。我为此使用 AngularJS。在我的 AuthenticateController 控制器中,我有登录方法,它在登录表单中提交时调用。实现如下所示:
function Login(username, password) {
// CreateLoginHeader creates the authorization token through the login values username and password
var authdata = CreateLoginHeader(username, password);
var config = {
withCredentials: true,
headers: { 'Authorization': authdata }
};
$http.post('http://XXXX', config).then(SuccessLogin, ErrorLogin);
}
有人知道这里出了什么问题吗?通过 chrome 开发人员工具,我可以看到我得到了错误 "XMLHttpRequest cannot load 'placeholder-server-URL'. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'placeholder-client-URL' is therefore not allowed access."。
我是否应该在客户端调用我的后端时添加这两个 header 值:
- Access-Control-Request-Method
- Access-Control-Request-Headers
选项请求未由 login
处理,因此未调用 createResponse
。
看看:https://blogs.oracle.com/theaquarium/entry/supporting_cors_in_jax_rs (you should implement a javax.ws.rs.container.ContainerResponseFilter
, see How to handle CORS using JAX-RS with Jersey)
此处代码的另一种可能性(但如果您开发 'real' 应用程序则不是):将 @javax.ws.rs.OPTIONS
添加到您的方法中,就像您对 @javax.ws.rs.POST
.