1

I deployed the php application with Apache with basic authentication enabled.

When accessing from local with ajax, the following error occurs.

Failed to load https://(myapp).herokuapp.com/api.php?mode=xxx: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 401.

My .htaccess setting is like this.

Header set Access-Control-Allow-Origin "*"
AuthUserFile /app/.htpasswd
AuthType Basic
AuthName "Restricted Access"
Require valid-user

And, My program is like this.

<button>Go!</button><br>
<textarea name="" id="result" cols="100" rows="10"></textarea>

<script src="./jquery-3.3.1.min.js"></script>
<script src="./jquery.base64.min.js"></script>
<script>
    var uri = "https://(myapp).herokuapp.com/api.php?mode=xxx";

    $('button').on('click', function() {
        $.ajax({
            url: uri,
            success: function(response) {
                $('textarea').val(response);
            },
            error: function(xhr, textStatus, errorThrown) {
                console.log(textStatus + " : " + errorThrown);
            },
            beforeSend: function(xhr) {
                var credentials = $.base64.encode("user:pass");
                xhr.setRequestHeader("Authorization", "Basic " + credentials);
            }
        });
    });
</script>

If basic authentication is disabled, data can be get successful.

So I think that it is Apache's problem rather than PHP.

Yuwaz
  • 383
  • 1
  • 4
  • 19
  • The server must be configured to not required authentication for CORS preflight OPTIONS requests. See the answer at https://stackoverflow.com/a/45406085/441757 – sideshowbarker Jun 22 '18 at 13:20
  • @sideshowbarker Thank you for your answer. I read the link, but eventually I could not figure out what to do. – Yuwaz Jun 22 '18 at 13:43

1 Answers1

0

I had a similar problem, and the issue was that I was not responding correctly to the CORS OPTIONS request. I use the heroku/php buildpack, not Apache, and use Silex to deploy my app. Your mileage may vary with other options.

Regardless -- I had to add an OPTIONS route, and then add the appropriate headers before sending back an HTTP 200 response. See code below. I have left in my logging that shows the request and response headers for reference. Hope it helps.

$app->options('/mv', function() use($app) {
    $app['monolog']->addDebug(">>> >>> >>> BEGIN RECEIVED HEADERS >>> >>> >>> ");
    foreach (getallheaders() as $name => $value) {
        $app['monolog']->addDebug(">>> $name: $value");
    }   
    $app['monolog']->addDebug(">>> >>> >>> END RECEIVED HEADERS >>> >>> >>> ");
    $app['monolog']->addDebug(">>> >>> ");

    header("Access-Control-Allow-Origin: *");
      header('Access-Control-Max-Age: 1000');
      header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
    header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization');
    header('HTTP/1.1 200');

    $app['monolog']->addDebug(">>> >>> ");
    $app['monolog']->addDebug(">>> >>> >>> BEGIN HEADERS SENT BACK >>> >>> >>> ");
    foreach (headers_list() as $name => $value) {
        $app['monolog']->addDebug(">>> $name: $value");
    }   
    $app['monolog']->addDebug(">>> >>> >>> END HEADERS SENT BACK >>> >>> >>> ");

    return json_encode(array());
});
jetsetter
  • 517
  • 5
  • 19