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

发布于 2024-12-27 05:00:37 字数 1719 浏览 2 评论 0原文

我使用 PHP 中的 Fat Free Framework 编写了一个 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>

我的网站应用程序在我的本地服务器上运行良好,并且仅在我的 Web 服务器上执行此操作。有什么想法出了什么问题吗?

I wrote a REST-ful API using Fat Free Framework in PHP, and am making a call using backbone.js. When I try and save a new Orders model my app makes a PUT request, and the server spits back a 406 error.

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

My .htaccess file looks like this:

# 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>

My website application works fine on my local server and only does this on my web server. Any ideas what is going wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

時窥 2025-01-03 05:00:37

我想出了一个解决方法。

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

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

为了保持我的 API REST 风格,我保留了 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 实现完好无损,并且只需在发布到网络服务器时注释掉 emulateHTTP 代码即可。

I came up with a workaround.

My believe my server is using mod_security2 to block PUT and DELETE requests. I am waiting to hear back from them, and mod_security2 can't be disabled in .htaccess files so there's nothing I can do.

Using "Script PUT /filename" in the .htaccess file was causing a 500 error: "Script not allowed here", I am not sure why, but I decided not to deal with having my web host reconfigured to handle PUT and DELETE.

To keep my API REST-ful, I left in the normal handling of PUT and DELETE, and added this to the POST handling:

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
}

If you set Backbone.emulateHTTP = true; it keeps the request method as POST and sends the X-HTTP-Method-Override as PUT or DELETE.

I like this because I can keep my REST-ful implementation intact, and just comment out the emulateHTTP code for when I publish to my webserver.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文