2013-10-16 83 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添加到路由並獲取一些數據。 –