java - 尝试使用 json 数据而不是纯文本或 x-www-form-urlencoded 进行 JQuery 发布时出现 CORS 问题
问题描述
问题/总结:
问题,我在使用应用程序 json 数据进行 jQuery 发布时收到 CORS 错误响应。但是对于带有纯文本/文本或 x-www-urlencoded-form 数据的 jQuery 帖子,我没有收到该错误。
问题/详细信息:
我在我的 Ubuntu VM 上运行了两个应用程序,一个运行在 React 应用程序上http://localhost:3000
,一个 Java Web 服务从我的 Netbeans 10 IDE 的 Payara 服务器运行在这个 urlhttp://cduran-virtualbox:8080/TestMavenWebApplication/firstservicecall
上。我正在尝试测试从 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 Posts(一种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);
}
});
这是我的带有 x-www-urlencoded-form 的 jQuery 帖子,它也适用:
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 响应:从 Servlet 返回您好 - 收到的内容类型 x-www-form-urlencoded
单击纯文本按钮后,此日志语句将显示在屏幕截图上,这再次证明 jQuery Post 工作正常:
纯文本响应:Hello back from Servlet - 内容类型收到纯文本
最后两条控制台日志消息是单击 Submit_json 按钮后的 CORS 错误响应。
编辑/更新 2:
附加说明 - 使用 Post Man 应用程序,我可以将带有 application/json 作为内容类型的 HTTP Post 发送到我的 Java Web 服务应用程序并看到响应。
我创建了一个常规的 Maven Java 应用程序(不是 Web 应用程序),我还可以将 application/json 作为内容类型的 HTTP Post 发送到我的 Java Web 服务应用程序,我可以在其中看到响应正常。
当我从我的 REACT Web 应用程序中提交带有 application/json 的 jQuery POST 时,我在 Web 浏览器上的开发人员工具的网页上看到 POST 作为 OPTION 发送(这发生在 Firefox 和 Chrome 浏览器中)。
此链接https://github.com/angular/angular/issues/22492中的评论提到发送简单请求,并列出不包含application/json
.
这确实使事情变得更加混乱。
编辑/更新 1:
这是我的后端服务器代码。没什么特别的,它只是检查 content-type 标头字段,然后解析对象并将不同的响应发送回 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-form-urlencoded
- 多部分/表单数据
- 文本/纯文本
尝试将“application/json”更改为其他内容类型,否则浏览器将执行预检请求。
请参阅 CORS 文档:https ://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
推荐阅读
- mysql - 无法在 MacOS 上启动 MySQL 服务器
- r - 根据日期键对多个 R 列表的值求和
- android - 使用opengl-es2在Android NDK中绘制纹理立方体不会绘制任何东西
- amazon-web-services - 使用 godaddy 域到 cloudfront / S3 的 HTTPS 连接
- php - Symfony (3.4) 应用程序:无法通过 .htaccess 将请求重定向到 /web 目录
- javascript - 无法使用 jQuery 向元素添加属性
- c++ - C++ 错误:在抛出 'std::bad_alloc' 的实例后终止调用
- python-3.x - 正在访问已删除的 css 文件并且 Web 应用程序正在运行这些文件
- java - 无法使用 Firebase 中的 Glide 库加载个人资料图片
- c# - 使用 DirectLine 访问机器人框架的本地实例