Javascript 由于CORS,HTTP post请求失败
我无法使我的应用程序运行。我一整天都在读这方面的文章,尝试了很多东西,但最后什么都没用。在最后一次尝试中,我尝试了这个。我的java后端是一个RESTful web服务,没有任何额外的框架,比如Jersey或RESTeasy,只是纯java。这里有我的登录帖子方法:Javascript 由于CORS,HTTP post请求失败,javascript,java,angularjs,cors,preflight,Javascript,Java,Angularjs,Cors,Preflight,我无法使我的应用程序运行。我一整天都在读这方面的文章,尝试了很多东西,但最后什么都没用。在最后一次尝试中,我尝试了这个。我的java后端是一个RESTful web服务,没有任何额外的框架,比如Jersey或RESTeasy,只是纯java。这里有我的登录帖子方法: @POST @Path("login") @Produces(value = "application/json") public Response login() { AccountAuthentificator aut
@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();
}
我还看到人们使用了另一种方法。它是用过滤器的,就像这样。我还想知道我的实现是否与此不同,飞行前的具体定义在哪里?在我的实现中,是.allow(“选项”)实现了这一点,但您可以纠正我的错误
然后我有了我的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 developer工具,我可以看到我出现了错误“XMLHttpRequest无法加载‘占位符服务器URL’。对飞行前请求的响应未通过访问控制检查:请求的资源上不存在‘访问控制允许源代码’头。因此,不允许访问源代码‘占位符客户端URL’。”
调用后端时,是否应在客户端添加这两个头值:
- 访问控制请求方法
- 访问控制请求头
登录处理,因此不调用createResponse
看看:(您应该实现一个javax.ws.rs.container.ContainerResponseFilter
,请参阅)
这里代码的另一种可能性(但如果您开发一个“真正”的应用程序,则不可能):将@javax.ws.rs.OPTIONS
添加到您的方法中,就像您对@javax.ws.rs.POST
所做的那样,登录不处理选项请求,因此不会调用createResponse
看看:(您应该实现一个javax.ws.rs.container.ContainerResponseFilter
,请参阅)
您的代码在这里的另一种可能性(但如果您开发一个“真正”的应用程序,则不会):将@javax.ws.rs.OPTIONS
添加到您的方法中,就像您在@javax.ws.rs.POST
中所做的那样,那么您为什么要进行跨域调用呢?CORS头与客户端无关,服务器需要添加它们。“RESTfulWeb服务,没有任何附加框架,如Jersey或RESTeasy”-你确定吗?请看:对不起,您是对的,我使用maven pom.xml文件中提供的javax:javax javaee api 7.0。是的,从我所读到的内容来看,我还认为CORS头必须只在服务器端@epascarello上实现。碰巧我遵循了另一个示例,通过编程添加了这些值。但据我所知,它们应该已经通过浏览器创建了。那你为什么要打跨域电话呢?CORS头与客户端无关,服务器需要添加它们。“RESTfulWeb服务,没有任何附加框架,如Jersey或RESTeasy”-你确定吗?请看:对不起,您是对的,我使用maven pom.xml文件中提供的javax:javax javaee api 7.0。是的,从我所读到的内容来看,我还认为CORS头必须只在服务器端@epascarello上实现。碰巧我遵循了另一个示例,通过编程添加了这些值。但据我所知,它们应该已经通过浏览器创建了。好的,我尝试了这种方法,我坚持使用教程。我唯一没有做的就是像他那样更改web.xml文件。我正在扩展应用程序类,并在其中添加我的类以及所有已定义的post/get方法。我还使用了过滤器的记录器,似乎在请求和响应中没有调用过滤器。知道为什么会这样吗?基本上这是我的应用程序类:@ApplicationPath(“/api/v1/brain”)公共类ApplicationConfig扩展应用程序{public Set>s=new hashset尝试以与StudyManagerService相同的方式注册过滤器(“提供者”)。这一更改完成了任务。我添加了两个过滤器类:s.add(StudyManagerService.class);s.add(RESTRequestFilter.class);s.add(restreponsefilter.class);
现在前端似乎出现了一个异常,但至少我又前进了一步。谢谢@meikou欢迎您,也许您可以将答案标记为正确;)好的,我尝试了这种方法,并且坚持使用教程。我唯一没有做的事情就是像他那样更改web.xml文件。我扩展了应用程序类,并在那里添加了我的类以及所有已定义的post/get方法。我还使用了过滤器记录器,似乎在请求和响应中没有调用过滤器。你知道吗是这样吗?基本上这是我的应用程序类:@ApplicationPath(“/api/v1/brain”)公共类应用程序配置扩展应用程序{public Set>s=new hashset尝试以与StudyManagerService相同的方式注册过滤器(“提供者”)。这一更改完成了任务。我添加了两个过滤器类:s.add(StudyManagerService.class);s.add(RESTRequestFilter.class);s.add(restreponsefilter.class);
现在前端似乎出现了一个异常,但至少我又前进了一步。谢谢@meikou欢迎您,也许您可以将答案标记为正确;)