我正在尝试构建一个Web服务(基于Java的服务器和Javascript基础客户端),我只需要发送带有json数据的Post请求,并且我需要从服务器获取带有json数据的post响应。因为客户端和服务器有我认为需要支持不同的域。到目前为止,我已经实现了这些:(我的客户端实现几乎与html5 rocs tutorial相同)
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<String> 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<Recommendation> 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,所以实际上我不知道这行代码的作用。谁能解释一下如果它存在或不存在会发生什么?
编辑2
我明白了,我需要把
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
为了发送带有请求的json。但是当我添加这个时,同样的错误又回来了。我应该向服务器添加什么才能实现此目的?
最佳答案
发生的情况是在初始请求之前发出了预检请求(这是一个 OPTIONS
请求)。因此,您需要一个 @OPTIONS 端点来处理该请求(即设置响应 header )。在当前代码中,您尝试在原始请求的端点响应中设置它,其中 OPTIONS 请求甚至无法到达。
更常见的方法是,无需为每个目标创建一个 @OPTIONS
端点,只需使用 Jersey filter as seen in this answer 。所有请求都会发送 header 。
另请参阅:
编辑
示例@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();
}
关于javascript - 如何摆脱基于 java 的 Web 服务服务器中请求的资源错误中存在 No 'Access-Control-Allow-Origin' header,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32034018/