如何摆脱在基于java的Web服务服务器中请求的资源错误上没有’Access-Control-Allow-Origin’标头

我正在尝试构建一个web服务(基于Java的服务器和Javascript基本客户端)我只需要发送一个带有json数据的Post请求,我需要从server获取一个json数据的post响应。因为客户端和服务器有不同的域我认为cors需要得到支持。 到目前为止,我已经实现了这些:(我的客户端实现与html5 rocs教程几乎相同)

Web服务客户端(js):

// I call client = new WSclient() in one of my js files WSclient=function(){ makeCorsRequest(); } // Create the XHR object. function createCORSRequest(method, url) { var xhr = new XMLHttpRequest(); if ("withCredentials" in xhr) { // XHR for Chrome/Firefox/Opera/Safari. xhr.open(method, url, true); } else if (typeof XDomainRequest != "undefined") { // XDomainRequest for IE. xhr = new XDomainRequest(); xhr.open(method, url); } else { // CORS not supported. xhr = null; } return xhr; } // Helper method to parse the title tag from the response. function getTitle(text) { return text; } // Make the actual CORS request. function makeCorsRequest() { // All HTML5 Rocks properties support CORS. var url = 'http://localhost:8080/myapp/myfunction'; var xhr = createCORSRequest('POST', url); xhr.setRequestHeader( 'X-Custom-Header', 'value'); xhr.send(); } 

Web服务器(java)

 @Path("/myapp/") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public class myFunctionClass { @POST @Path("myfunction") public Response recommendations(User inf){ // From the client I also need to send json // like {"name":"john","surname":"smith","name":"marry","surname":"smith"} // and if possible I want to put this infformation inside inf object List infos = inf.getInformation(); // here I call one of the my methods to get recommendations // I remove it for simplicity and just put type of recommendations object // list recommendations= runFunction(infos); final StringWriter sw =new StringWriter(); final ObjectMapper mapper = new ObjectMapper(); mapper.writeValue(sw, recommendations); System.out.println(sw.toString()); sw.close(); return Response.ok(sw.toString(), MediaType.APPLICATION_JSON).header("Access-Control-Allow-Origin", "*") .header("Access-Control-Allow-Methods", "POST").allow("OPTIONS").build(); } } 

但是,我想我需要做更多的事情,因为当我运行这些时,我得到了

  XMLHttpRequest cannot load http://localhost:8080/myapp/myfunction. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. 

那么我应该添加到我的服务器代码中以摆脱这个错误? 此外,我如何在客户端的请求中发送json数据? 这是我第一次处理这样的问题,如果我的问题有点荒谬,抱歉。

编辑

当我删除

  xhr.setRequestHeader( 'X-Custom-Header', 'value'); 

部分来自客户端,它工作正常。 正如我之前所说,这是我第一次使用网络服务和javascript,所以实际上我不知道这行代码是什么。 谁能解释一下如果它存在与否会发生什么?

EDIT2

我明白了,我需要提出来

 xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); 

为了发送带请求的json。但是当我添加它时,同样的错误又回来了。 我应该向服务器添加什么才能实现此目的?

发生的事情是在初始请求之前有一个预检请求(这是一个OPTIONS请求)。 因此,您需要一个@OPTIONS端点来处理该请求(即设置响应头)。 在当前代码中,您尝试在原始请求的端点响应中设置它,OPTIONS请求甚至无法到达。

一种更常见的方法,而不是为每个目标创建一个@OPTIONS端点,只需使用泽西filter,如本答案中所示 。 标题将被发送给所有请求。

也可以看看:

  • HTTP访问控制(CORS)

编辑

示例@OPTIONS

 @OPTIONS @Path("myfunction") public Response cors() { return Response.ok() .header("Access-Control-Allow-Origin", "*") .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD") // whatever other CORS headers .build(); }