Cors Policity Error: It does not have HTTP ok status

I have created my own restful application in PHP that exposes APIs to javascript application. Everything works smoothly except when I insert http_response_code in the response header.

Below is the function I use to print the data in json format. I set the http_response_code() based on the error code I need to use (200, 404, 400, 401 etc).

<?php

public function handle($code = 200, $data = array())
{
    $message = json_encode(
        array(
            "code" => $code,
            "data" => $data
        ), JSON_PRETTY_PRINT
    );
        
    http_response_code($code);

    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Headers: *");
    header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE");
    header('Content-type: text/javascript; charset=utf-8'); 
        
    print_r($message);
    exit;
}

Frontend side, I make simple Ajax calls with jQuery. I don’t think it needs any explanation but I put it for completeness.

$.ajax({
    url: url,
    method: method,
    cache: false,
    headers: headers,
    data: data,
    crossDomain: true, 
    success: function(data){
        console.log(data)
    },
    error: function (xhr, ajaxOptions, thrownError) {
        console.log((xhr.responseJSON)
    }
});

The problem is this. If in the PHP script I comment the line http_response_code($code); Everything works smoothly, but I always receive as status code 200.

If I try to change the status code, be it 200 or any other code, the client responds with the following error:

Access to XMLHttpRequest at 'MY API URL CENSORED' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

As you can see both php and js side I have enabled cross domain and enabled all cross-origin. I don’t really understand why it gives me this error, only if I add this line http_response_code($code).

Am I doing something wrong? Can changing the status code create any kind of problem with cors policies?

Answer

Am I doing something wrong?

Something about the request you are making (it isn’t clear what as everything that could trigger this is hidden behind variables you haven’t shared) requires a preflight request.

The browser will therefore make an OPTIONS request asking permission to make the actual (e.g. POST) request.

You appear to be responding to the preflight request as if it were the aactal request.

Can changing the status code create any kind of problem with cors policies?

Yes. The response to the preflight request must (as the error message says) have a 200 OK status in order for the browser to accept that permissions have been granted to make the actual request.

The response to the actual request can have whatever status you like.

You can differentiate them by testing if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {