由于 CORS 导致 HTTP 发布请求失败
Posted
技术标签:
【中文标题】由于 CORS 导致 HTTP 发布请求失败【英文标题】:Failed HTTP post request because of CORS 【发布时间】:2016-06-18 21:51:17 【问题描述】:我无法让我的应用程序运行。我整天都在读这个,尝试了很多东西,但最后没有任何效果。在最后一次尝试中,我尝试了这个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 方法基本上添加了必要的标头,如您在此处看到的:
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 控制器中,我有 Login 方法,在登录表单中提交时调用该方法。实现如下所示:
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 无法加载'placeholder-server-URL'。对预检请求的响应未通过访问控制检查:没有'Access-Control-Allow-Origin'标头存在于请求的资源。因此,不允许访问源“占位符-客户端-URL”。”。
在调用后端时,我是否应该在客户端添加这两个标头值:
访问控制请求方法 访问控制请求标头【问题讨论】:
那你为什么要进行跨域调用呢? CORS 标头与客户端无关,服务器需要添加它们。 '没有任何额外框架(如 Jersey 或 RESTeasy)的 RESTful Web 服务' - 你确定吗?见:***.com/tags/jax-rs/info 对不起,你是对的,我使用 javax:login
不处理 Options 请求,因此不调用 createResponse
。
看看:https://blogs.oracle.com/theaquarium/entry/supporting_cors_in_jax_rs(你应该实现一个javax.ws.rs.container.ContainerResponseFilter
,见How to handle CORS using JAX-RS with Jersey)
您的代码在这里的另一种可能性(但如果您开发一个“真正的”应用程序则不是):将@javax.ws.rs.OPTIONS
添加到您的方法中,就像您对@javax.ws.rs.POST
所做的那样。
【讨论】:
好的,我尝试过这种方式,并且坚持使用教程here。我唯一没有做的就是像他一样更改 web.xml 文件。我正在扩展 Application 类并在其中添加我的类以及所有已定义的 post/get 方法。我还将记录器用于过滤器,似乎没有在请求和响应上调用过滤器。知道为什么会这样吗? 基本上这是我的应用程序类:@ApplicationPath("/api/v1/brain") public class ApplicationConfig extends Application public Set<Class<?>> getClasses() Set<Class<?>> s = new HashSet<Class<?>>(); s.add(StudyManagerService.class); return s;
尝试像 StudyManagerService 一样注册过滤器(“提供者”)。
这一改变起到了作用。我添加了我的两个过滤器类:s.add(StudyManagerService.class); s.add(RESTRequestFilter.class); s.add(RESTResponseFilter.class);
现在似乎我在前端有一个例外,但至少我更进一步。谢谢@meiko
不客气,也许您可以将答案标记为正确;)以上是关于由于 CORS 导致 HTTP 发布请求失败的主要内容,如果未能解决你的问题,请参考以下文章
每当 CORS $http 请求失败时,返回的响应始终为 0
2021-09-13 一文解析前端请求307导致CORS跨域失败