2013-10-16 383 views
7

我正在尝试创建一个RESTful Web服务,并且已经陷入了实现PUT请求的困境。我已经尝试过,并且未能遵循本网站上的其他解答以及Mozilla的各种文章。CORS预检请求返回HTTP 405

该请求是从域wwwtest.dev-box生成的,它将转到test.dev-box(基本上是调用后端应用程序的前端应用程序)。下面是我从现场HTTP头拍摄的头:

http://test.dev-box/resource/v1/data/user/1 

OPTIONS /resource/v1/data/user/1 HTTP/1.1 
Host: test.dev-box 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-US,en;q=0.5 
Accept-Encoding: gzip, deflate 
Origin: http://wwwtest.dev-box 
Access-Control-Request-Method: PUT 
Connection: keep-alive 

HTTP/1.1 405 Method Not Allowed 
Date: Wed, 16 Oct 2013 16:15:58 GMT 
Server: Apache/2.2.15 (Red Hat) 
x-powered-by: PHP/5.3.27 
Access-Control-Allow-Origin: http://wwwtest.dev-box 
Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS 
Access-Control-Max-Age: 1728000 
Content-Length: 0 
Allow: PUT 
Cache-Control: no-cache 
Connection: close 
Content-Type: text/html; charset=UTF-8 

我使用了一个框架,以便一切都被路由到web.php,其中包含在页面的顶部下面的代码(从this MDN article拍摄) :

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { 
    header('Access-Control-Allow-Origin: http://wwwtest.dev-box'); 
    header('Access-Control-Allow-Methods: POST, GET, PUT, OPTIONS'); 
    header('Access-Control-Max-Age: 1728000'); 
    header("Content-Length: 0"); 
    header("Content-Type: text/plain"); 
} else { 
    header("HTTP/1.1 403 Access Forbidden"); 
    header("Content-Type: text/plain"); 
} 

之前我的代码,使得它发出的CORS预检OPTIONS请求第一(你可以从上面的捕捉看到)PUT请求。必要的标题应附加到响应并告诉请求者PUT被允许。不幸的是,从上面的响应头中可以看到,即使PUT在响应access-control-allow-methods中,它仍然返回405方法不允许。

这是框架.htaccess文件我使用(捷希凯):

<IfModule mod_rewrite.c> 
    Options -MultiViews 

    RewriteEngine On 
    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteRule^web.php [QSA,L] 
</IfModule> 

回答

12

我发现答案是Apache和框架配置之间的交叉。

  1. 对于Apache的配置,你可以把下列您的虚拟主机的指令,或请求的域的.htaccess文件(如果它是在.htaccess记得IfModule mod_headers.c标签封装)。在页面上设置标头的mod_rewrite重定向到不工作:

    页眉设置访问控制允许来源“http://wwwtest.dev-box

    页眉设置访问控制允许的方法“GET,POST,HEAD, DELETE,PUT,OPTIONS“

  2. 对于Silex配置,请将以下内容放入应用程序路径中。它基本上发送一个HTTP 200 OK来接收任何OPTIONS请求。典论Silex Google Group发现:

    $ APP->比赛( “{URL}”,函数($网址)使用($ APP){ 回报 “OK”; }) - >断言( 'URL', ) - >方法( “选项”) '*';

需要完成这两个步骤才能让RESTful应用程序正常工作。

3

的405是在参照实际预检/ OPTIONS请求。您的服务器直接拒绝预检,因为您的服务器不接受一般的OPTIONS请求。您需要修改您的服务器配置才能接受OPTIONS请求。只需将代码包含在PHP文件中可能不够。很有可能您的Web /应用程序服务器不知道此动词,并在请求到达您的PHP代码之前拒绝该请求。

+0

我还没有听说过任何我读过的文章中的Apache阻止OPTIONS请求。你有没有关于这方面的任何信息,或者我如何配置它的想法? –

+0

嗯,仔细一看,你的PHP代码似乎正在执行,因为CORS头包含在响应中。然后,您的PHP代码中最有可能返回一个405。你将不得不发布你所有的PHP代码。 –

+0

不可能发布代码,但我使用Silex,这是一个基于Symfony2的框架,如果有帮助的话。我没有做任何限制访问权限或修改头文件等内容。只是尝试将PUT添加到路由并获取一些数据。 –