尝试使用json数据执行JQuery post时出现CORS问题,但不能使用纯文本或x-www-form-urlencoded
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了尝试使用json数据执行JQuery post时出现CORS问题,但不能使用纯文本或x-www-form-urlencoded相关的知识,希望对你有一定的参考价值。
发行/概述:
问题,我在使用应用程序json数据执行jQuery帖子时收到CORS错误响应。但是我没有使用普通/文本或x-www-urlencoded-form数据获得jQuery帖子的错误。
发行/详细信息:
我在我的Ubuntu VM上运行了两个应用程序,一个在http://localhost:3000
上运行的React应用程序,以及一个从我的Netbeans 10 IDE在这个url http://cduran-virtualbox:8080/TestMavenWebApplication/firstservicecall
上从Payara Server运行的Java Web服务。我正在尝试测试从React应用程序到Web服务使用不同内容类型的不同jQuery帖子。
为了避免收到CORS错误消息,我将其添加到java Web服务器HttpServletRequest对象response.addHeader("Access-Control-Allow-Origin", "http://localhost:3000");
但是,在使用Json数据执行jQuery帖子时,我收到此错误:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://cduran-virtualbox:8080/TestMavenWebApplication/firstservicecall. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
但我有两个其他测试方法做jQuery帖子(一个content-type
是text/plain
,另一个是application/x-www-form-urlencoded
没有那个问题。即我成功地可以发送一个jQuery Post消息到Web服务并得到回复。
这里是带有json数据的jQuery Post的代码,我有CORS响应问题:
var urlToPost = 'http://cduran-VirtualBox:8080/TestMavenWebApplication/firstservicecall';
$.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json; charset=utf-8',
//crossDomain: true,
url: urlToPost,
async:true,
data: JSON.stringify({ Object: 'CD', Quantity: '4' }),
success: function(response) {
console.log("json response: " + response);
},
failure: function(errMsg) {
alert(errMsg);
}
});
这是jQuery帖子的纯文本工作(即没有CORS响应,我可以看到到达的Web服务代码,我可以看到响应这个启动jQuery帖子的React应用程序):
var urlToPost = 'http://cduran-VirtualBox:8080/TestMavenWebApplication/firstservicecall';
$.ajax({
type: "POST",
//dataType: "text",
contentType: 'text/plain',
url: urlToPost,
data: "Hello from CommunicationForm (plain text)",
success: function(response) {
console.log("plain text response: " + response);
}
});
这是我的jQuery帖子与x-www-urlencoded-form也有效:
var myObject = {
var1: 'Hello from CommunicationForm'
};
var urlToPost = 'http://cduran-VirtualBox:8080/TestMavenWebApplication/firstservicecall';
$.ajax({
type: "POST",
//dataType: "text",
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
url: urlToPost,
data: myObject,
success: function(response) {
console.log("application/x-www-form-urlencoded response: " + response);
}
});
作为进一步的证据,这里是我的React应用程序的屏幕截图,您可以忽略输入文本字段,因为它什么都不做。但我有3个输入提交按钮。从按钮名称可以推断出,上面的jQuery帖子使用x-www-urlencoded-form内容类型,另一个使用text / plain,另一个使用json。
单击x-www ..按钮后,将从Web服务接收此日志语句(如屏幕截图所示)(表示它正常工作)。
application / x-www-form-urlencoded response:来自Servlet的Hello - 收到的内容类型x-www-form-urlencoded
单击明文按钮后,此日志语句将显示在屏幕截图上,再次证明jQuery Post工作正常:
纯文本响应:从Servlet返回Hello - 内容类型接收纯文本
最后两个控制台日志消息是单击Submit_json按钮后的CORS错误响应。
编辑/更新2:
附加说明 - 使用Post Man应用程序,我可以将带有application / json的HTTP Post作为内容类型发送到我的Java Web服务应用程序并查看响应。
我创建了一个常规的Maven Java应用程序(不是Web应用程序),我还可以将带有application / json的HTTP Post作为内容类型发送到我的Java Web服务应用程序,我可以看到响应很好。
当我从我的REACT网络应用程序提交带有application / json的jQuery POST时,我在Web浏览器上的开发人员工具的网页上看到POST作为OPTION发送(这在Firefox和Chrome浏览器中都有发生)。
此链接中的评论https://github.com/angular/angular/issues/22492提到发送简单请求,并列出不包含application/json
的内容类型。
这确实让事情变得更加混乱。
编辑/更新1:
这是我的后端服务器代码。没有什么特别的,它只是检查内容类型头字段,然后解析对象并将不同的响应发送回React应用程序。
public class FirstServlet extends HttpServlet {
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
String contentType = request.getHeader("content-type");
response.addHeader("Access-Control-Allow-Origin", "http://localhost:3000");
if (contentType.equals("text/plain")) {
InputStream is = request.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = "";
while((line = br.readLine()) != null) {
System.out.println("Plain/Text data received: " + line);
}
response.getWriter().print("Hello back from Servlet - content type received plain text");
} else if (contentType.equals("application/x-www-form-urlencoded; charset=utf-8")) {
String msgReceived = request.getParameter("var1");
System.out.println("Message Received: " + msgReceived);
response.getWriter().print("Hello back from Servlet - content type received x-www-form-urlencoded");
} else if (contentType.toLowerCase().contains("json")) {
JSONObject json = new JSONObject(request.getParameterMap());
System.out.println("json data received: " + json.toString());
response.getWriter().print("Hello back from Servlet - content type received application/json");
} else {
response.getWriter().print("Hello back from Servlet - content type undefined");
}
}
}
简单请求中Content-Type标头的唯一值如下:
- 应用程序/ x-WWW窗体-urlencoded
- 多部分/格式数据
- 纯文本/
尝试将“application / json”更改为其他内容类型,否则浏览器将执行预检请求。
请参阅CORS文档:https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
CORS完全依赖于响应中的Access-Control-Allow-Origin标头值,并且似乎对具有json内容类型的请求的响应未接收到此标头。
我认为具有JSON内容类型的请求可能在服务器端失败,并且标头“Access-Control-Allow-Origin”仅为成功请求设置。
您是否通过在response.addHeader("Access-Control-Allow-Origin", "http://localhost:3000");
上调试点来检查它是否因为JSON内容类型请求而被点击?
你可以分享一下这个标题设置的服务器代码吗?
对不起,我在答案部分询问我的问题而不是评论,因为我现在无法发表评论。
编辑:更新了应用程序/ json内容类型POST查询的Jquery代码。请分享请求的原始格式,如果不起作用,可以在“网络”选项卡下看到。由于请求的格式不正确,因此它没有达到服务器端的实现,这也就是为什么没有在响应中设置标头。
var urlToPost = 'http://cduran-VirtualBox:8080/TestMavenWebApplication/firstservicecall';
$.ajax({
url: urlToPost,
type: "POST",
contentType: 'application/json',
data: JSON.stringify({ “Object”: “CD”, “Quantity”: “4” }),
success: function(response) {
console.log("json response: " + response);
},
failure: function(errMsg) {
alert(errMsg);
}
});
我想我可能已经找到了这个问题,进一步巩固了Indrajit Bhaskaran在上面的回答。
根据这个链接https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers#Directives
请注意,始终允许某些标头:Accept,Accept-Language,Content-Language,Content-Type(但只能使用其解析值的MIME类型(忽略参数)application / x-www-form-urlencoded,multipart / form-data,或text / plain)。这些称为简单标头,您无需明确指定它们。
上面提到的关键是,只允许从网站到请求后端的3种内容类型。
以上是关于尝试使用json数据执行JQuery post时出现CORS问题,但不能使用纯文本或x-www-form-urlencoded的主要内容,如果未能解决你的问题,请参考以下文章
nginx,jquery - 执行 POST 时出现 Access-Control-Allow-Origin 错误
尝试使用 json 数据而不是纯文本或 x-www-form-urlencoded 进行 JQuery 发布时出现 CORS 问题
将 JSON 数据从 JQuery 发送到 WCF REST 方法时出现问题