XMLHttpRequest cannot load resource
<p>I'm trying to make a simple php backend to handle a contact form in another server, but despite adding the proper headers, it keeps giving me the same error message:</p>

<pre><code>XMLHttpRequest cannot load https://php-contact-form-lual.herokuapp.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4000' is therefore not allowed access. The response had HTTP status code 404.
</code></pre>

<p><br>
This is the ajax request:</p>

<pre><code>$.ajax({
    type: 'POST',
    url: 'https://php-contact-form-lual.herokuapp.com/',
    data: {
            subject: 'subject',
            to: 'receiver',
            name: $('#name').val(),
            email: $('#email').val(),
            msg: $('#msg').val()
            }
    }) // then the callbacks
</code></pre>

<p><br>
and this is the php:</p>

<pre><code>&lt;?php

    if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  // return only the headers and not the content
  // only allow CORS if we're doing a POST - i.e. no saving for now.
  if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) &amp;&amp; $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST') {
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Headers: X-Requested-With');
  }
  exit;
}

// handling the data    
$subject = $_POST['subject'];
$to      = $_POST['to'];
$name    = $_POST['name'];
$email   = $_POST['email'];
$msg     = $_POST['msg'];
$msg     = "DE: " . $name . " (" . $email .")" . "\n\n" . $msg;

mail($to, $subject, $msg);

?&gt;
</code></pre>

<p>Notice that the lines of code before the "handling the data" block are taken from <a href="https://stackoverflow.com/a/18399709/5326490">this answer</a>, I also tried with the simpler solution presented in the first part of that same answer -found also elsewhere-, and even replacing the asterisk with the specific URL, but the result has been the same :(</p>

<p>Any help would be appreciated :)</p>

<p><br>
<strong>Update: log of the things I've tried on the server side (from oldest to current):</strong></p>

<pre><code>// Allow from any origin
if (isset($_SERVER['HTTP_ORIGIN'])) {
    header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
    header('Access-Control-Allow-Credentials: true');
    header('Access-Control-Max-Age: 86400');    // cache for 1 day
}

// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {

    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         

    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
        header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");

    exit(0);
}

------------------------------------------

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, OPTIONS");

-----------------------------------------

header("Access-Control-Allow-Origin: http://localhost:4000");
header("Access-Control-Allow-Methods: POST, OPTIONS");

-----------------------------------------

header("Access-Control-Allow-Origin: http://localhost:4000");
header("Access-Control-Allow-Methods: POST, OPTIONS, GET");

-----------------------------------------

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) &amp;&amp; $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST') {
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers');
    }
    exit;
}

------------------------------------------

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) &amp;&amp; $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST') {
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers');
    }
    exit;
}

// + sending headers though ajax

------------------------------------------

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers');

-------------------------------------------

# created .htaccess file with this line:
Header set Access-Control-Allow-Origin "*" 

------------------------------------------

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS, GET');
header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers');

---------------------------------------------

header('Access-Control-Allow-Origin: http://localhost:4000');
header('Access-Control-Allow-Methods: POST, OPTIONS, GET');
header('Access-Control-Allow-Headers: X-Requested-With, content-type, access-control-allow-origin, access-control-allow-methods, access-control-allow-headers');

-----------------------------------------------

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  // return only the headers and not the content
  // only allow CORS if we're doing a POST - i.e. no saving for now.
  if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) &amp;&amp; $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST') {
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Headers: X-Requested-With');
  }
  exit;
}

--------------------------------------------------

header('Origin: http://localhost:4000');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
</code></pre>

<p><br>
<strong>Aditional info</strong></p>

<p>Request headers</p>

<pre><code>POST / HTTP/1.1
Host: php-contact-form-lual.herokuapp.com
Connection: keep-alive
Content-Length: 88
Accept: */*
Origin: http://localhost:4000
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:4000/contacto/
Accept-Encoding: gzip, deflate, br
Accept-Language: es,en-GB;q=0.8,en;q=0.6,de;q=0.4
</code></pre>

<p>Response headers</p>

<pre><code>HTTP/1.1 404 Not Found
Connection: keep-alive
Date: Sat, 17 Dec 2016 16:10:02 GMT
Server: Apache
Content-Length: 198
Content-Type: text/html; charset=iso-8859-1
Via: 1.1 vegur
</code></pre>