Backbone & Slim PHP - Access-Control-Allow-Headers - Can GET information, can't POST it?

时间秒杀一切 提交于 2019-11-30 05:28:51

I had a similar cross domain POST problem (in fact with all headers except GET). The following resolved it:

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && (   
       $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST' || 
       $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'DELETE' || 
       $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'PUT' )) {
             header('Access-Control-Allow-Origin: *');
             header("Access-Control-Allow-Credentials: true"); 
             header('Access-Control-Allow-Headers: X-Requested-With');
             header('Access-Control-Allow-Headers: Content-Type');
             header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT'); // http://stackoverflow.com/a/7605119/578667
             header('Access-Control-Max-Age: 86400'); 
      }
  exit;
}

In your javascript client you're making an OPTIONS request to /user/auth, but in your PHP code you're only accepting POST requests through this endpoint.

If you want your API to accept OPTIONS method you should have something like this in your code:

$app->options('/user/auth', function () use ($app) {
    //code here
});

Or, if you want to handle multiple HTTP methods in the same function:

$app->map('/user/auth', function () use ($app) {
    if ($app->request()->isOptions()) {
        //handle options method
    }

    else if ($app->request()->isPost()) {
        //handle post method
    }
})->via('POST', 'OPTIONS');

Keep in mind that the OPTIONS method, according to W3C:

[...] represents a request for information about the communication options available on the request/response chain identified by the Request-URI. This method allows the client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval.

Alternatively, just change your client's code to make a POST request instead of OPTIONS request. It's easier and makes more sense than authenticating a user through the OPTIONS method. In zepto.js it would be something like this:

$.post('/user/auth', { foo: 'bar' }, function(response){ 
    console.log(response);
});

Your OPTIONS request should be a 200 returning an empty response. Then the browser will send the real POST request.

Also no need to add OPTIONS in Access-Control-Allow-Methods header.

It seems your using authentication, why not add Access-Control-Allow-Credentials header too.

For more informations check this code it may be helpful.

CorsSlim helped me. https://github.com/palanik/CorsSlim

<?php 
$app = new \Slim\Slim();
$corsOptions = array("origin" => "*",
"exposeHeaders" => array("Content-Type", "X-Requested-With", "X-authentication", "X-client"),
"allowMethods" => array('GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'));
$cors = new \CorsSlim\CorsSlim($corsOptions);
$app->add($cors);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!