Issue/Summary:
Issue, i get a CORS error response when doing a jQuery post with application json data. But I don't get that error with jQuery posts with plain/text or x-www-urlencoded-form data.
Issue/Details:
I have two apps running on my Ubuntu VM, a React app running on http://localhost:3000
and a Java web service running from a Payara Server from my Netbeans 10 IDE at this url http://cduran-virtualbox:8080/TestMavenWebApplication/firstservicecall
. I'm trying to test doing different jQuery Posts with different content types from the React app to the web service.
To avoid getting a CORS error message I added this to the java web server HttpServletRequest object response.addHeader("Access-Control-Allow-Origin", "http://localhost:3000");
However I'm getting this error when doing a jQuery post with Json data:
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).
But i have two other test methods that do jQuery Posts (one where the content-type
is text/plain
and the other is application/x-www-form-urlencoded
that don't have that issue. i.e. I successfully can send a jQuery Post message to the web service and get a response back.
Here's the code of the jQuery Post with json data where I have the CORS response issue:
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);
}
});
Here's the jQuery post with plain text that works (ie no CORS response, i can see the web service code being reached, and i can see the response back to this React app that initiated the jQuery post):
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);
}
});
Here's my jQuery post with x-www-urlencoded-form that also works:
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);
}
});
As further evidence, here's a screen shot of my React app, you can ignore the input text field as it does nothing. But I have 3 input submit buttons. As can be inferred from the button names, one does the jQuery post above with x-www-urlencoded-form content type, the other does text/plain, and the other json.
After clicking the x-www.. button this log statement ( as shown in the screenshot) is received back from the web service (indicating it works fine).
application/x-www-form-urlencoded response: Hello back from Servlet - content type received x-www-form-urlencoded
After clicking the plaintext button this log statement is shown on the screen shot which again proves that the jQuery Post works fine:
plain text response: Hello back from Servlet - content type received plain text
The last two console log messages are the CORS error response after clicking the Submit_json button.
EDIT/UPDATE 2:
Additional notes - Using the Post Man app I can send the HTTP Post with application/json as the content type to my Java web service app and saw the response.
I created a regular Maven Java app (not web app) and I can also send an HTTP Post with application/json as the content type to my Java web service app, and I can see the response fine in it.
When I submitted the jQuery POST with application/json from my REACT web app I saw on the network page of the developer tools on the web browser that the POST is sent as an OPTION (this happened in both Firefox and Chrome browsers).
A comment in this link https://github.com/angular/angular/issues/22492 mentions to send simple requests, and lists out content types that don't include application/json
.
This does make things more confusing.
EDIT/UPDATE 1:
Here's my back end server code. Nothing too especial, it just checks the content-type header field and then parses the object and sends a different response back to the React app.
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");
}
}
}
The only values for the Content-Type header in a simple request are the following:
Try to change the "application/json" to other content type or the browser will do a preflight request.
Refer to the CORS documentation: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS