2011-11-16 21 views
34

にPOSTを変更します。XMLHttpRequestのは、私はこのコードを持っている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を持っています同じオリジン政策の問題ですか?私は、allow-originヘッダーを置くためにrestletを変更して、私は別のGET httpリクエスト(jquery内)でテストし、okでも動作します。私はhtml5ブラウザを使用し、私のサーバは応答にヘッダーを入れるので、同じ起源の問題が解決されているので、なぜこのエラーが表示されますか? OPTIONのPOSTを変更する理由 ありがとう!

可能性の重複は?:私はノーだと思うが、それは本当だ、問題は両方の質問に対して同じ ですが、鉱山はまず、ブラウザの問題、およびその他がある ことを質問するので参照されていますjqueryを指します。経験では時間は重複してカウントされませんが、 の回答は異なりますが、どちらの質問も互いに を補完することは事実です。

+0

可能な複製の[GET要求の代わりにOPTIONS要求を取得するのはなぜですか?](https://stackoverflow.com/questions/1256593/why-am-i-getting-an-options-request-instead-of-a -get-request) – Carvallegro

答えて

56

はい、これは「同じ発信元ポリシーの問題」です。別のサーバーまたは別のポートに要求を出しています。つまり、サイト間のHTTP要求です。特に、GET以外のHTTPメソッド、またはと POSTの使用のために(

また、 サーバーのデータへの副作用を引き起こす可能性がありますHTTPリクエストメソッドのために:ここではそのような要求について言いたいことthe documentationです特定のMIMEタイプ)では、 ブラウザーは、HTTPのOPTIONS要求メソッドを使用して、サポートされているメソッドを のサーバーから要求してから、サーバーからの「承認」を に送信し、実際の要求を実際の HTTPリクエストメソッド。

さらに詳しくは、CORS standard(「プリフライトを使用したクロスオリジン要求」セクション)を参照してください。あなたのサーバはOPTIONSリクエストを許可し、リクエストを可能にするAccess-Control-Allow-Origin,Access-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の中でそれを処理する方法です:あなたは任意の原点からのCORS要求を許可する場合

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; 
    } 
} 

、置き換え、

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

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

承認を使用しない場合は、このビットは不要です:

私がやってしまったものを、POSTおよびオプションを取得し、 X-App-Idヘッダので、この私たち: 私は3つのリクエストメソッドをホワイトリストに登録するために必要な開発していAPIについては
add_header Access-Control-Allow-Headers "Authorization"; 
add_header Access-Control-Allow-Credentials "true"; 

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; 
} 
関連する問題