OPTIONS request not reaching the server

I am making POST requests by sending and receiving JSON in my PHP API. When I'm on localhost it works as expected, but when I'm in production I get the error below in chromium:

OPTIONS http://myserver.com/my-dir/api/person/exists net::ERR_EMPTY_RESPONSE

And in firefox:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://myserver.com/my-dir/api/person/exists. (Reason: CORS request did not succeed).[Learn More]
Error: "0"
    onreadystatechange http://examplesite.com/js/app.ec842a5c.js:1:25207

On the server I have:

header("Access-Control-Allow-Origin: http://examplesite.com");
header("Content-Type: multipart/form-data; application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Expose-Headers: Authorization");
header("Access-Control-Allow-Headers: Origin, Content-Type, Access-Control-Allow-Headers, Access-Control-Allow-Credentials, Authorization, X-Requested-With");

if($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
   http_response_code(200);
   echo json_encode(array("message" => "OK!"));
   exit(0);
}

No Client:

const request = new XMLHttpRequest();
request.onreadystatechange = function() {
  if(request.readyState === XMLHttpRequest.DONE) {
    if(request.status === 200) {
      console.log(request);
    }
  }
}
request.onerror = function() {
  console.log(Error("Network Error"));
};
request.open('POST', 'http://myserver.com/my-dir/api/person/exists', true);
const jwt = localStorage.getItem('jwt');
if(jwt) {
  request.withCredentials = true;
  request.setRequestHeader('Authorization', 'Baerer ' + jwt);
}
request.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
request.setRequestHeader('Accept', 'application/json');
request.send(JSON.stringify(data));

Chromium Headers:

General

Request URL: http://myserver.com/my-dir/api/person/exists
Referrer Policy: no-referrer-when-downgrade

Request Headers

Provisional headers are shown
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Origin: http://examplesite.com
Referer: http://examplesite.com/
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36

Firefox Headers:

Request URL: http://myserver.com/my-dir/api/person/exists
Request method: OPTIONS

Request headers (482 B) 
Accept  
text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8
Accept-Encoding 
gzip, deflate
Accept-Language 
en-US,en;q=0.5
Access-Control-Request-Headers  
content-type
Access-Control-Request-Method   
POST
Cache-Control   
max-age=0
Connection  
keep-alive
DNT 
1
Host    
myserver.com
Origin  
http://examplesite.com
User-Agent  
Mozilla/5.0 (X11; Linux x86_64…) Gecko/20100101 Firefox/60.0

In localhost works, but when I switch to " http://examplesite.com " it doesn't work. I don't know what the problem is for me to try to solve, what seems to be happening is the OPTIONS request is not even arriving on the server.

Up

On the server if I already put in the first lines of my file " index.php":

http_response_code(401);
echo json_encode(array("message" => "Not authorized."));
exit(0);

I still get the same errors, it is as if the request did not even arrive on the server.

I do a test using CURL:

eu@eu:~$ curl -X POST http://myserver.com/my-dir/api/person/exists
{"message":"Not authorized."}

And it works as expected.

Maybe something is wrong in the client.

Author: PerduGames, 2019-07-23

1 answers

Finally found the problem, and it was the "Content-Type" header that I'm adding in the client request.It is not necessary to include it, the browser will do the work for you, they were being the reason for the error, since when I add the Line:

request.setRequestHeader('Content-Type', 'application/json; charset=utf-8')

I get the error:

OPTIONS http://myserver.com/my-dir/api/person/exists net::ERR_EMPTY_RESPONSE

When I comment on it, everything works as expected. So my code looked like this on the server:

header("Access-Control-Allow-Origin: http://examplesite.com");
header("Content-Type: multipart/form-data; application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Credentials: true"); 
header("Access-Control-Max-Age: 3600");
header("Access-Control-Expose-Headers: Authorization");
header("Access-Control-Allow-Headers: Origin, Content-Type, Authorization");

if($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
   http_response_code(200);
   echo json_encode(array("message" => "OK!"));
   exit(0);
}

No client:

const request = new XMLHttpRequest();
request.onreadystatechange = function() {
  if(request.readyState === XMLHttpRequest.DONE) {
    if(request.status === 200) {
      console.log(request);
    }
  }
}
request.onerror = function() {
  console.log(Error("Network Error"));
};
request.open('POST', 'http://myserver.com/my-dir/api/person/exists', true);
const jwt = localStorage.getItem('jwt');
if(jwt) {
  request.withCredentials = true;
  request.setRequestHeader('Authorization', 'Baerer ' + jwt);
}
request.send(JSON.stringify(data));

With this is working, the strange is in the localhost does not receive the error, and when when it is in production Yes, I still do not quite understand the reason, the browser does not help by giving a more detailed error message. I believe it is because in localhost the 'Content-Type' was not being added for some reason and everything worked fine. But I don't really know, anyway, it worked again after removing this line from the code.

 1
Author: PerduGames, 2019-07-24 01:15:09