title: XMLHttpRequest cannot load resource
body: <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>