2012-01-15 33 views
2

我在PHP中使用Fat Free Framework编写了一个REST-ful API,并使用backbone.js进行调用。当我尝试保存一个新订单模型时,我的应用程序发出一个PUT请求,并且服务器吐出一个406错误。PUT请求返回来自Backbone.js的406(不可接受)返回到我的REST-ful PHP页面

Request Method:PUT 
Status Code:406 Not Acceptable 

Request Headers 
Accept:application/json, text/javascript, */*; q=0.01 
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 
Connection:keep-alive 
Content-Length:174 
Content-Type:application/json 
Cookie:__utma=239804689.76636928.1286699220.1305666110.1325104376.94; __utmz=239804689.1325104376.94.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); PHPSESSID=935d2632fd0d12a1a0df4cb0f392eb5e 
X-Requested-With:XMLHttpRequest 

Request Payload 
{"id":0,"customerId":0,"lastPage":"items","priceConfig":null,"items":null,"saveStatus":0,"savedAt":1326588395899,"name":null} 

Response Headers 
Connection:Keep-Alive 
Content-Length:460 
Content-Type:text/html; charset=iso-8859-1 
Date:Sun, 15 Jan 2012 00:46:37 GMT 
Keep-Alive:timeout=5, max=98 
Server:Apache 

我的.htaccess文件看起来是这样的:

# Enable rewrite engine and route requests to framework 
RewriteEngine On 
RewriteBase/
RewriteCond %{REQUEST_FILENAME} !-l 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule .* index.php [L,QSA] 

# Disable ETags 
<IfModule mod_headers.c> 
    Header Unset ETag 
    FileETag none 
</IfModule> 

# Default expires header if none specified (stay in browser cache for 7 days) 
<IfModule mod_expires.c> 
    ExpiresActive On 
    ExpiresDefault A604800 
</IfModule> 

<IfModule mod_security.c> 
SecFilterEngine Off 
SecFilterScanPOST Off 
</IfModule> 

我的网站应用程序工作正常,我的本地服务器上,只有做到这一点我的Web服务器上。任何想法出了什么问题?

+0

您是否在某处添加了['Script'](http://httpd.apache.org/docs/current/mod/mod_actions.html#script)指令来告诉Apache如何处理PUT请求? [见此](http://php.net/manual/en/features.file-upload.put-method.php)。 – DaveRandom 2012-01-15 01:06:41

+0

添加“脚本PUT(任何目录/文件)”给我一个500内部服务器错误 – 2012-01-15 02:56:04

+0

在无脂框架(所有路由通过index.php完成)我使用下列路由PUT请求/订单:F3 :: route( 'PUT/orders',dostuff());也许这是困惑的是,index.php正在调用PUT本身?我不明白Apache如何处理路由选择。 – 2012-01-15 03:00:01

回答

1

我想出了一个解决方法。

我相信我的服务器正在使用mod_security2来阻止PUT和DELETE请求。我正在等待他们回复,并且无法在.htaccess文件中禁用mod_security2,所以我无能为力。

在.htaccess文件中使用“脚本PUT /文件名”导致500错误:“脚本不允许在这里”,我不知道为什么,但我决定不处理让我的Web主机重新配置为处理PUT和DELETE。

让我的REST API-FUL,我留在PUT的正常处理和删除,并已将此添加到POST处理:

function post() { 
    //if Backbone.emulateHTTP is true, emulate PUT 
    $data = json_decode(F3::get('REQBODY'), true); 
    $type = $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']; //PUT, DELETE, POST 
    if ($type == 'PUT') { 
     $this->put(); 
     return; 
    } 
    if ($type == 'DELETE') { 
     $this->delete(); 
     return; 
    } 

    //handle normal POST here 
} 

如果设置Backbone.emulateHTTP = TRUE;它将请求方法保存为POST,并将X-HTTP-Method-Override作为PUT或DELETE发送。

我喜欢这个,因为我可以保持我的REST-ful实现完整,并且只是在我发布到我的web服务器时注释掉emulateHTTP代码。

+0

更新:此解决方法运行良好,并且我的主机能够为我的网站禁用mod_security。哪个让我改变Backbone.emulateHTTP = false;一切都按预期工作。 – 2012-01-16 21:38:28

相关问题