OPTIONS request not reaching the server

Asked

Viewed 488 times

1

I am making POST requests by sending and receiving JSON in my PHP API. When I’m on the localhost it works as expected, but when I’m in production I get the error below on 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);
}

On the 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));

The Headers of the Chromium:

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

The Headers of firefox:

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

On localhost it works, but when I switch to "http://examplesite.com" does not work. I do not know what is the problem for me to try to solve, what seems to be happening is the OPTIONS request is not even coming to the server.

up

In the server if I put already 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’s like the request didn’t 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 works as expected.

Maybe something is wrong with the customer.

  • If I’m not mistaken your client’s request should have this header, request.setRequestHeader('Access-Control-Allow-Origin', 'http://examplesite.com');

  • @Augustovasques It doesn’t make sense for the request to have this header, because this is the header the server uses to tell the browser which sources it accepts. But as in the case of CORS I try everything, I tried but it didn’t work.

  • 1

    https://www.html5rocks.com/en/tutorials/cors/

1 answer

1

I finally found the problem, and it was the "Content-Type" header that I’m adding to the client’s request. It is not necessary to include it, the browser will do the job for you, they were being the reason for the error, because 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 looks 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);
}

On the 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 working, the strange thing is in localhost not receiving the error, and when it is in production yes, I still do not understand very well the reason, the browser does not help giving a more detailed error message. I believe it is because in localhost was not being added the 'Content-Type' for some reason and everything worked well. But I really don’t know, anyway, it worked again after removing that line from the code.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.