2016-03-24 7 views
0

私は自分自身でC++とBoostライブラリで開発したHTTPサーバーをテストしています。具体的には、JSONがPUTによって受信されるエンドポイントをテストしています。なぜAJAXによるPOSTの送信は、HTTPサーバーによってOPTIONSとして解釈され、CURLによる送信は事実上PUTですか?

response_jsonを送信するJSONを持つファイルである

curl -H "Content-Type: application/json" -H "Content-Length: 34" -H "Connection: close" -X PUT --data "@response_json" http://localhost:8080/answer

:私は、次のコマンドを使用してカールを使用してRESTfulなWebサービスをテストするには

。これは正常に動作し、サーバーはPUTとして要求を受け取り、何をすべきかを行います。

しかし、私はこれでAJAXからWebサービスをテストする場合:

function sendPut2() { 
    var http = new XMLHttpRequest(); 
    var url = 'http://localhost:8080/answer'; 
    var data = JSON.stringify({"question": "a", "answer": "b"}); 
    http.open("PUT", url, true); 
    http.setRequestHeader("Content-type", "application/json"); 
    http.setRequestHeader("Content-Length", data.length); 
    http.setRequestHeader("Connection", "close"); 
    http.onreadystatechange = function() { 
     if(http.readyState == 4 && http.status == 200) { 
      alert(http.responseText); 
     } 
    } 
    http.send(data); 
} 

サーバはOPTIONSとしてそれを受け取り、動作しませんが。さらに、Firebugコンソールでは、「NetworkError:404 Not Found - http://localhost:8080/answer」と表示されます。

私はFirefoxとChromeで試しました。私のJavaScriptコードで何が間違っていますか?

これは、JavaScriptからの要求とFirebugのです:ブラウザはセキュリティ上の理由から、同一生成元ポリシーを持っている

Firebug

+0

同じ原点に当たっていることを確認し、同じ原点に2つのオプションがないかどうかを確認してください。 1.サーバーはaccess-control-allow-originsヘッダーで応答する必要があります。 2.一時的にchrome corsプラグインをインストールする – everlasto

+0

Chrome CORSプラグインはOPTIONSの問題を本当に解決しません。場合によっては '--disable-web-security'コマンドラインオプションを使ってchromeをテストするほうが良いでしょう。 –

答えて

2

。ブラウザでAjax PUTを現在のWebページがロードされたものとは異なる起点から要求すると、その要求は同じ起点ポリシーの対象となります。宛先サイトは、ブラウザが実装する特定の方式であるCORS(クロスオリジンリソース共有)をサポートすることを選択できます。これにより、特定のクロスオリジン要求がOKかどうかをターゲットサイトに尋ねることができます。

PUT要求の前にOPTIONS要求を使用することは、CORS方式のそのような部分の1つです。ブラウザが元のクロス起点リクエストで特定の条件を検出すると、OPTIONSリクエストが最初に発行され、それから正しい応答が得られた場合、ターゲットリクエスト(ケースのPUT)が発行されます。 OPTIONSリクエストを使用するためにブラウザを起動できるものは、カスタムヘッダー、特定の種類の許可、特定のコンテンツタイプ、特定の種類のリクエストなどのようなものです。

CURLは、最初のOPTIONSリクエストからの正解を必要とせずに、PUTリクエストをすぐに送信するだけで、同じ起源セキュリティ(これは、独自のWebページセキュリティモデル用に開発されたブラウザを使用しています)。 Ajaxリクエストを行っているブラウザでJavaScriptはJavascriptが含まれてロードされたウェブページと同じ起源から要求している場合、それが可能になるので


FYI、それはOPTIONS要求をトリガするべきではありませんクロスオリジン要求ではなく、同じオリジン要求。ローカルサーバーがある場合は、Webサーバーがローカルサーバー(同じホスト名とポート番号)からロードされていることを確認してください。ファイルシステムからではなく、IPアドレスを使用しないでください。 。ブラウザーに関する限り、ホスト名は同じIPアドレスではなく物理的に同じでなければなりません。

Preflighted requests

Unlike simple requests (discussed above), "preflighted" requests first send an HTTP request by the OPTIONS method to the resource on the other domain, in order to determine whether the actual request is safe to send. Cross-site requests are preflighted like this since they may have implications to user data. In particular, a request is preflighted if:

It uses methods other than GET, HEAD or POST. Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted. It sets custom headers in the request (e.g. the request uses a header such as X-PINGOTHER)

はFYI、ここでCORSのさまざまな側面のpretty good explanationです:


は、ここで要求がOPTIONS要求で "プリフライト" されているものにMDNからの情報です。あなたの要求はPUTなので、その記事の「あまりにも単純な要求」の部分になります。

関連する問題