Reputation: 7729
I have a form in a HTML page which does the following:
form method="POST" id="myForm" onsubmit="callSlates();">
Javascript function is as follows:
function callSlates(){
var form=document.getElementById('myForm');
form.action = "https://dev1-apiservicesweb.dev.jabs.com:8111/api/v1/systems/slates";
// collect the form data while iterating over the inputs
var data = {};
for (var i = 0, ii = form.length; i < ii; ++i) {
var input = form[i];
if (input.name == "ID1") {
data[input.name] = input.value;
}
if (input.name == "SDCode") {
data[input.name] = input.value;
}
}
var xhr = new XMLHttpRequest();
xhr.open('POST', form.action);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
}
xhr.send(JSON.stringify(data));
}
//return false;
}
POST calls are happening but when I check the Request Header, it shows that the application/x-www-form-urlencoded
and am ending with error 504-Gateway Timeout Error
The endpoint I am calling expects json header and JSON data. I believe I am doing that but when I used Chrome developer tools, I don't see that. Has it got something to do with the way am making the call?
Edit: When I tried hitting that URL with Postman, with header and body as JSON, am getting 200 response (as expected).
UPDATE: I understood that the form was getting submitted rather than the Ajax call and thus took Barmar
advice and put return false;
in form onsubmit. Now am not getting 504 anymore and getting 405 instead.
Following is the request header am seeing currently:
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:dev1-apiservicesweb.dev.jabs.com:8111
Origin:http://localhost:3000
And in general information, it says:
Request Method:OPTIONS
Status Code:405
As per le_m
, could this be a CORS issue?
Upvotes: 0
Views: 2650
Reputation: 20248
Since your request works from your local host via postman but not from within the browser, the culprit is probably the Same Origin Policy:
Your browser attempts to send a Cross Origin Request (CORS). There are two types of CORS requests:
Preflighted requests: The browser first asks the server about supported HTTP methods by sending an HTTP OPTIONS request followed by the actual HTTP request upon approval.
Simple requests: The browser directly sends the actual HTTP request.
Now, which of the above does your browser choose? MDN states that simple requests will be send if the Content-Type
is one of the following:
application/x-www-form-urlencoded
multipart/form-data
text/plain
However, Content-Type: application/json
is not allowed for simple requests. Thus, you currently send preflighted CORS requests. You can verify that by opening the developer console e.g. in Firefox: You will notice that your code first sends an OPTIONS request.
Now, this OPTIONS request receives a 405 Method not allowed error. This indicates that the server doesn't support preflighted CORS requests. You either need to change the server configuration OR change the Content-Type
to one of the compatible ones listed above. If your server can't accept one of those content types, then you are probably out of luck.
See also this answer given by @ArslanTariq in reply to a similar issue.
Upvotes: 2
Reputation: 782166
You're not preventing the normal form submission. Change your form to:
<form method="POST" id="myForm" onsubmit="callSlates();return false;">
return false;
prevents the default submit action.
There's also no need to set form.action
in your function, since you don't want to submit the form normally.
Upvotes: 0