2016-04-16 23 views
6

jQuery AJAXを使用してWebサービスにクエリを作成しています。私のクエリは次のようになります。jQuery AJAX呼び出しの結果がエラー状態403

var serviceEndpoint = 'http://example.com/object/details?version=1.1'; 
$.ajax({ 
    type: 'GET', 
    url: serviceEndpoint, 
    dataType: 'jsonp', 
    contentType: 'jsonp', 
    headers: { 'api-key':'myKey' }, 
    success: onSuccess, 
    error: onFailure 
}); 

私はこれを実行すると、ステータスコード403を有する点で、私の呼び出しの結果は、私が上のセキュリティの制御によ、なぜ、私は理解していない403のステータスエラーを取得します私のサービスとそれはワイドオープンとしてマークされています。私は鍵が有効であることを知っています。なぜなら、私は別の呼び出しでそれを使用しているからです。

私はこれらが2つの異なるエンドポイントであることを知っています。しかし、私はこれがサーバー側の認証または許可エラーではないと100%確信しています。もう一度、すべてがサーバー側で広く開いています。つまり、クライアント側のリクエストで間違いをしています。

私はこの要求が開発中に行われていると伝えなければならないと感じています。だから、私はhttp://localhost:3000から実行しています。その理由から、私はすぐにそれがCORSの問題であると仮定しました。しかし、すべてが正しいように見えます。私のPOSTリクエストは機能しますが、GETは私には絶対に欲求不満です。何か不足していますか?どうなり得るか?

+2

ブラウザでそのURLを直接開こうとしましたか? URLの '/ data /'部分が欠落していますか? – charlietfl

+1

'jsonp'リクエストにヘッダを送ることはできません。これはスクリプトリクエストです。あなたは 'jsonp'ではなく' jsonp'を望んでいますか?ヘッダーの 'JSON.stringify()'もなぜですか? GETは 'contentType'を要求しません。ボディコンテンツが送信されていないためです。いずれかの問題が発生する可能性のある問題が多数あります。 – charlietfl

+0

@charlietflブラウザで開こうとしました。私はインクルードする必要がある '/ data /'の部分に慣れていません。私はlitterally 'バージョン'と 'api-key 'を渡す必要があります。ヘッダーとして 'api-key'を置くべきだと思っていました。 'data'と' contentType'のプロパティを 'jsonp'に設定する必要がありますか?これは単純な呼び出しでなければならないようです。しかし、明らかに、私はそれをボクシングして何かを見落としています。正しい呼び出しはどうすればよいですか? –

答えて

12

403エラーの理由はです。あなたはヘッダーを送信していません。 CORS要求を行っているので、サーバがこれらのヘッダを有効にしない限り、カスタムヘッダを送信することはできません。Access-Control-Allow-Headersを応答に追加します。

preflighted-requestでは、クライアントはサーバーに対して2つの要求を行います。最初のものはプリフライト(OPTIONメソッド付き)で、もう1つは実際のリクエストです。サーバーは、プリフライト要求の応答としてAccess-Control-Allow-Headersヘッダーを送信します。したがって、いくつかのヘッダを送ることができます。このようにして、POSTリクエストはプリフライトリクエストであるため、POSTリクエストが機能します。しかし、GETリクエストの場合、Access-Control-Allow-Headersヘッダーを収集するプリフライトはありません。したがって、ブラウザはカスタムヘッダーを送信しません。

この問題の回避策:回避策として

、以下のようjsonにごdataTypecontentTypeを設定します。

var serviceEndpoint = 'http://example.com/object/details?version=1.1'; 
$.ajax({ 
    type: 'GET', 
    url: serviceEndpoint, 
    dataType: 'json', 
    contentType: 'json', 
    headers: { 'api-key':'myKey' }, 
    success: onSuccess, 
    error: onFailure 
}); 

この方法では、あなたのGETリクエストはpreflighted requestになります。お使いのサーバーでのAccess-Control-Allow-Headersヘッダーが有効になっている場合は動作します。 (express.jsで書かれた)上記要求に対する

サンプルサーバー構成:

res.setHeader('Access-Control-Allow-Origin', '*'); 
res.setHeader('Access-Control-Allow-Methods', '*'); 
res.setHeader('Access-Control-Allow-Headers', 'api-key,content-type'); 
res.setHeader('Access-Control-Allow-Credentials', true); 

加えた:JSONP要求をしながら

実際、contentTypeapplication/javascript又はapplication/jsonのいずれかであるべきです。 jsonpとしてcontentTypeはありません。

+0

res.setHeaderコードを書きますか?また、どのような種類のオブジェクトがresですか? – Zoran777

+0

@ Zoran777それはサーバー側になります。 'express'サーバの' res'のための[こちらのドキュメントはこちら](http://expressjs.com/en/api.html#app.get.method)です。 – ykaragol

0

あなたはjQueryのAjax呼び出しのためAPI pageを見れば、それはコンテンツタイプ]セクションで次のように述べて:

注:クロスドメインリクエストについては、他の何でも にコンテンツタイプを設定しますapplication/x-www-form-urlencoded、multipart/form-data、または text/plainよりも前に、プリフライトのOPTIONS 要求をサーバーに送信します。

  • Preflight Blob Request
  • HTML 5ロックスUsing CORS
  • :ページが本当に何であるか「プリフライトOPTIONS要求」に言及しませんが、オンラインそのフレーズを検索するとき、私はいくつかの興味深いリンクを発見した

  • W3CのCross-Origin Resource Sharingスペック
  • Using CORS for Cross-Domain Ajax Requests
  • HTML5Rocksページのcode example & CORS imageです。画像はJavaScriptコードからブラウザへのAjax呼び出しがサーバーにどのように行われているかを示しています&どの3つの応答がラウンドトリップしているかを示しています。

    当社では、JavaScript +ブラウザ=クライアントと考える傾向がありますが、イラストの作者は、ウェブ開発者のコ​​ード&前者はJavaScriptコードで記述されているブラウザの開発者のコ​​ード、との違いを説明しているが、後者は書かれていましたC、C++またはC#コードを使用します。

    良いパケットアナライザツールはFiddlerです。これはWiresharkに似ています。これらのツールのいずれかは、ブラウザからサーバーに送信されている飛行前のリクエストを表示する必要があります。おそらく、それはあなたのAjaxリクエストがサーバーによってブロックされている場所で、403 Forbidden errorです。

    関連する問題