2012-11-08 18 views
4

我使用Backbone和Slim PHP框架。我想發佈信息到我的API,但訪問控制允許報頭一直引起我的問​​題......Backbone&Slim PHP - Access-Control-Allow-Headers - 可以獲取信息,無法發佈嗎?

我的控制檯上寫着:

OPTIONS http://api.barholla.com/user/auth 405 (Method Not Allowed) zepto.min.js:2 
XMLHttpRequest cannot load http://api.barholla.com/user/auth. Request header field Content-Type is not allowed by Access-Control-Allow-Headers. 

我的頭寫着:

Request URL:http://api.barholla.com/user/auth 
Request Method:OPTIONS 
Status Code:405 Method Not Allowed 
Request Headersview source 
Accept:*/* 
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3 
Accept-Encoding:gzip,deflate,sdch 
Accept-Language:en-US,en;q=0.8 
Access-Control-Request-Headers:origin, content-type, accept 
Access-Control-Request-Method:POST 
Connection:keep-alive 
Host:api.barholla.com 
Origin:http://localhost 
Referer:http://localhost/barholla/app/ 
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4 
Response Headersview source 
Access-Control-Allow-Origin:* 
Allow:POST 
Connection:close 
Content-Type:application/json 
Date:Thu, 08 Nov 2012 16:12:32 GMT 
Server:Apache 
Transfer-Encoding:chunked 
X-Powered-By:Slim 
X-Powered-By:PleskLin 

我在我的苗條index.php文件標題是:

$res = $app->response(); 
$res->header('Access-Control-Allow-Origin', '*'); 
$res->header("Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS"); 

爲了處理後的數據:

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

在我的JavaScript(我使用的骨幹框架)我的代碼是:

App.userAuth = new App.UserAuthModel({ 
    username: $('#username').val(), 
    password: hex_md5($('#password').val()) 
}); 

App.userAuth.save({}, { 
    success: function(model, resp) { 
    console.log(resp); 
    }, 
    error: function(model, response) { 
    console.log(response); 
    } 
}); 

任何幫助將不勝感激,我已經被困在了好久了!

回答

16

我也有類似的跨域POST問題(其實所有的標題除了GET)。以下解決它:

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; 
} 
+0

Thanks!創造了我的一天 – emccracken

3

您的OPTIONS請求應該是200返回空響應。然後瀏覽器將發送真正的POST請求。

也不需要在Access-Control-Allow-Methods標題中添加OPTIONS。

它似乎是您使用身份驗證,爲什麼不添加Access-Control-Allow-Credentials標題了。

有關更多信息,請檢查此code或許有幫助。

5

在JavaScript客戶端,你正在做一個OPTIONS請求/用戶/ AUTH,但在你的PHP代碼你只接受通過這個端點POST請求。

如果你希望你的API接受OPTIONS方法,你應該有這樣的事情在你的代碼:

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

或者,如果你想處理在同一功能的多個HTTP方法:

$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'); 

請記住,OPTIONS方法,according to W3C

[...]表示用於請求有關通過Request-URI標識的請求/響應鏈上可用的通信選項的信息。此方法允許客戶端確定與資源相關的選項和/或要求或服務器的功能,而不會暗示資源操作或啓動資源檢索。

或者,只需更改您的客戶端的代碼以發出POST請求而不是OPTIONS請求。這比通過OPTIONS方法驗證用戶更容易,更有意義。在zepto。JS這將是這樣的:

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

CorsSlim幫助我。 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); 
相關問題