PUT请求将来自Backbone.js的406(不可接受)返回到我的REST-ful PHP页面

PUT请求将来自Backbone.js的406(不可接受)返回到我的REST-ful PHP页面,php,apache,rest,backbone.js,fat-free-framework,Php,Apache,Rest,Backbone.js,Fat Free Framework,我在PHP中使用Fat-Free框架编写了一个REST-ful API,并且正在使用backbone.js进行调用。当我尝试保存一个新的订单模型时,我的应用程序发出一个PUT请求,服务器返回一个406错误 Request Method:PUT Status Code:406 Not Acceptable Request Headers Accept:application/json, text/javascript, */*; q=0.01 Accept-Charset:ISO-8859-1,

我在PHP中使用Fat-Free框架编写了一个REST-ful API,并且正在使用backbone.js进行调用。当我尝试保存一个新的订单模型时,我的应用程序发出一个PUT请求,服务器返回一个406错误

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>
#启用重写引擎并将请求路由到框架
重新启动发动机
重写基/
重写cond%{REQUEST_FILENAME}-L
重写cond%{REQUEST_FILENAME}-F
重写cond%{REQUEST_FILENAME}-D
重写规则。*index.php[L,QSA]
#禁用ETag
标题未设置ETag
FileTag无
#如果未指定,则默认过期标头(在浏览器缓存中停留7天)
过期于
到期默认A604800
分离过滤器发动机关闭
secfilters可以关闭

我的网站应用程序在本地服务器上运行良好,并且只在web服务器上运行。你知道怎么回事吗

我想出了一个解决办法

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

在.htaccess文件中使用“Script PUT/filename”会导致一个500错误:“此处不允许使用脚本”,我不确定原因,但我决定不处理将web主机重新配置为处理PUT和DELETE的问题

为了保持API的完整性,我保留了正常的PUT和DELETE处理,并将其添加到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代码。

您是否在某个地方添加了一条指令,告诉Apache如何处理PUT请求。添加“Script PUT(any directory/file)”在无脂肪框架中给了我500个内部服务器错误(所有路由都是通过index.php完成的),我将PUT请求路由到/orders,使用:F3::route('PUT/orders',dostuff());可能是因为对index.php本身调用PUT感到困惑?我不明白Apache是如何处理路由问题的。我怀疑您仍然需要
Script
指令-默认情况下,Apache不会调用PHP脚本来处理PUT请求,因此无论您在PHP代码中配置/编写什么,它都不会被执行。我必须设置一个PHP脚本来处理一次通过Apache的PUT请求,我似乎记得它花了我相当长的时间才开始工作……当你收到一个500错误时,你在Apache日志中看到了什么消息?更新:这个解决方法工作得很好,我的主机能够为我的站点禁用mod_安全性。这让我改变了主干。emulateHTTP=false;一切都按预期进行。