Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XMLHttpRequest cannot load resource

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:

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.


This is the ajax request:

$.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


and this is the php:

<?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']) && $_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);

?>

Notice that the lines of code before the "handling the data" block are taken from this answer, 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 :(

Any help would be appreciated :)


Update: log of the things I've tried on the server side (from oldest to current):

// 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']) && $_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']) && $_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']) && $_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');


Aditional info

Request headers

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

Response headers

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
like image 270
Lual Avatar asked Dec 17 '16 04:12

Lual


2 Answers

I see that the server is returning a 404 error. This suggests that you do not have the PHP code above inside the index.php file under https://php-contact-form-lual.herokuapp.com/index.php.

Also, consider whether you really need https. Does the server also accept single http requests, and if so, why don't you try to use it without SSL?

Finally, did you try to pass the data as JSON data using the jQuery $.ajax dataType: "jsonp" and JSON.stringify({}) an object for the $.ajax data?

like image 100
Christos Lytras Avatar answered Nov 15 '22 13:11

Christos Lytras


The problem is the 404 status code. It's not even reaching the code you're typing.

  1. Do you have a

    $app->post('/', function() use($app) {
        // This is the route you need to edit.
    });
    
  2. Do you have any "when" or other condition for the route? If so, remove it for now.

  3. You must has configuration specific for https? I also note that you have different settings on http (403) vs. https (404), by default Heroku delivers the same code for both http and https unless you set in config for Silex.

  4. Once you get that working (i.e. not a 404), you'll need to return the Access-Control-Allow-Origin header at the same time as the response (as you have in one of the "what I tried" examples. Having an "exit" after that will actually prevent the content being returned which is not totally helpful. (You need "exit" after redirect/location headers, but not here).


Other notes:

  • If you're trying to create a "simple" PHP backend, why go for Heroku? You're not really coding PHP, but coding Symphony, Silex, Twig and all the other libraries that mean you're in documentation and library overkill.
  • As you are using Heroku, there's a SwiftMailer interface (will help you make the mail() secure!
like image 44
Robbie Avatar answered Nov 15 '22 14:11

Robbie