2011-11-16 91 views
34

我有這樣的代碼:XMLHttpRequest的變化POST到OPTION

net.requestXHR = function() { 
    this.xhr = null; 
    if(window.XMLHttpRequest === undefined) { 
     window.XMLHttpRequest = function() { 
      try { 
       // Use the latest version of the activex object if available 
       this.xhr = new ActiveXObject("Msxml2.XMLHTTP.6.0"); 
      } 
      catch(e1) { 
       try { 
        // Otherwise fall back on an older version 
        this.xhr = new ActiveXObject("Mxsml2.XMLHTTP.3.0"); 
       } 
       catch(e2) { 
        //Otherwise, throw an error 
        this.xhr = new Error("Ajax not supported in your browser"); 
       } 
      } 
     }; 
    } 
    else 
     this.xhr = new XMLHttpRequest(); 
} 
net.requestXHR.prototype.post = function(url, data) { 
    if(this.xhr != null) { 
     this.xhr.open("POST", url); 
     this.xhr.setRequestHeader("Content-Type", "application/json"); 
     this.xhr.send(data); 
    } 
} 

    var rs = new net.requestSpeech(); 
    console.log(JSON.stringify(interaction)); 
    rs.post("http://localhost:8111", JSON.stringify(interaction)); 

當發送執行,我有這個日誌:

OPTIONS http://localhost:8111/ [HTTP/1.1 405 Method Not Allowed 74ms] 

而在本地主機:8111我有一個reslet serverResource接受交,這是同源策略的問題?我修改restlet以放置允許來源的標題,我用另一個GET請求(在jquery中)測試它,並且工作正常。我有同樣的來源解決問題,因爲我使用html5瀏覽器,並且我的服務器把頭部放在響應中,所以爲什麼發送給我這個錯誤?爲什麼要改變POST的OPTION? 謝謝!

可能的複製?:我覺得沒什麼,但它是真實的,但問題是這兩個問題的 一樣,但我是指因爲這個問題是 存在與瀏覽器的問題,另一方面,第一指向 jquery。根據經驗,時間不計算重複, 答案是不同的,但是這兩個問題都相互補充 是真的。

+0

[爲什麼我會得到OPTIONS請求而不是GET請求?](https://stackoverflow.com/questions/1256593/why-am-i-getting-an-options-request-instead-of-a -get-request) – Carvallegro

回答

56

是的,這是「同源政策的問題」。您正在向不同的服務器或不同的端口發送請求,這意味着這是一個跨站點HTTP請求。下面是the documentation不得不說的這樣的請求:

此外,對於HTTP請求方法,可能會導致在 服務器的數據副作用(特別是比GET其它HTTP方法,或 POST用法同某些MIME類型),規範要求 瀏覽器「預檢」請求,請求支持的方法從 服務器採用HTTP OPTIONS請求方法,然後在 從服務器「批准」,發送實際請求與實際 HTTP請求方法。

CORS standard(「帶有預檢的跨源請求」部分)中有更詳細的描述。您的服務器需要允許OPTIONS請求,併發送回應Access-Control-Allow-OriginAccess-Control-Allow-HeadersAccess-Control-Allow-Methods頭允許請求。然後瀏覽器會發出實際的POST請求。

+1

如果我無法修改服務器的行爲,我該怎麼辦?我無法訪問它的源代碼 – gbaor

+1

@gbaor:您可以使用沒有同源限制的[JSONP](http://en.wikipedia.org/wiki/JSONP),或者(如果服務器不支持這一點)你可以在你自己的服務器上運行一個服務器端腳本,它將請求來自其他服務器的數據並返回它 - 然後你的JavaScript代碼可以從你的服務器獲取這個數據,這個數據是相同的。 –

9

我在發送ajax內容的JavaScript代碼中遇到了這個問題。

爲了讓與預檢跨地請求我不得不這樣做在接受了請願書在.aspx:

//Check the petition Method 
if (Request.HttpMethod == "OPTIONS") 
{ 
    //In case of an OPTIONS, we allow the access to the origin of the petition 
    string vlsOrigin = Request.Headers["ORIGIN"]; 
    Response.AddHeader("Access-Control-Allow-Origin", vlsOrigin); 
    Response.AddHeader("Access-Control-Allow-Methods", "POST"); 
    Response.AddHeader("Access-Control-Allow-Headers", "accept, content-type"); 
    Response.AddHeader("Access-Control-Max-Age", "1728000"); 
} 

你必須要小心,並檢查正在什麼標題你的請願書問了。我使用Fiddler檢查了那些。

希望這能爲將來的人服務。

1

正如其他人指出的,這是一個CORS的事情。

這是如何(基於 this source)來處理它在NGINX:

location/{ 
    if ($request_method = OPTIONS) { 
     add_header Access-Control-Allow-Origin "http://example.com"; 
     add_header Access-Control-Allow-Methods "GET, OPTIONS"; 
     add_header Access-Control-Allow-Headers "Authorization"; 
     add_header Access-Control-Allow-Credentials "true"; 
     add_header Content-Length 0; 
     add_header Content-Type text/plain; 
     return 200; 
    } 
} 

如果你想允許從任何來源CORS請求,更換,

add_header Access-Control-Allow-Origin "http://example.com"; 

add_header Access-Control-Allow-Origin "*"; 

如果您不使用授權,則不需要此位:

add_header Access-Control-Allow-Headers "Authorization"; 
add_header Access-Control-Allow-Credentials "true"; 

對於我發展我的API需要加入白名單3種請求方法:GET,POST和OPTIONS和X-App-Id頭,所以這個我們什麼我落得這樣做:

if ($request_method = OPTIONS) { 
    add_header Access-Control-Allow-Origin "*"; 
    add_header Access-Control-Allow-Methods "GET, POST, OPTIONS"; 
    add_header Access-Control-Allow-Headers "X-App-Id"; 
    add_header Content-Length 0; 
    add_header Content-Type text/plain; 
    return 200; 
}