web-dev-qa-db-ja.com

カスタムヘッダーReactJSを使用したGETリクエストの取得

APIにGETリクエストを送信しようとしていますが、コードにカスタムヘッダーを追加すると、奇妙なことが起こります。 Webサーバーに到達すると、どこかでリクエストメソッドがOPTIONSに変わります。

しかし、ヘッダーなしで同じことをすると、GETタイプになります。アプリケーションポストマン(API開発ツール)を使用すると、リクエストは正常に機能します。

リクエストコード:

    let token = this.generateClientToken(privateKey, message);

    let myheaders = {
      "appID": appID,
      "authorizationkey": token
    }

    fetch('http://localhost:8080/api/app/postman', {
      method: "GET",
      // body: JSON.stringify(''),
      headers: myheaders
    }).then(function(response) {
      console.log(response.status);     //=> number 100–599
      console.log(response.statusText); //=> String
      console.log(response.headers);    //=> Headers
      console.log(response.url);        //=> String

      return response.text()
    }, function(error) {
      console.log(error.message); //=> String
    })
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

サーバーログの出力(ヘッダー付き):

worker_1  | 172.18.0.4 -  17/Mar/2017:15:47:44 +0000 "OPTIONS /index.php" 403
web_1     | 172.18.0.1 - - [17/Mar/2017:15:47:44 +0000] "OPTIONS /api/app/postman HTTP/1.1" 403 5 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:54.0) Gecko/20100101 Firefox/54.0" "-"

サーバーログ出力(ヘッダーなし):

worker_1  | 172.18.0.4 -  17/Mar/2017:16:01:49 +0000 "GET /index.php" 403
web_1     | 172.18.0.1 - - [17/Mar/2017:16:01:49 +0000] "GET /api/app/postman HTTP/1.1" 403 5 "http://localhost:3000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:54.0) Gecko/20100101 Firefox/54.0" "-"

追加のブラウザーでフェッチをサポートするためのNPMモジュールを追加しました。
https://github.com/github/fetch#obtaining-the-response-url
https://github.com/taylorhakes/promise-polyfill

ここで何が欠けていますか?それはすべて私にとって正しいように見えます。

Firefox開発版を使用して、NPM起動で実行してReactjsアプリをテストしています

9
Steven Bakker

おそらく、cors npmパッケージ https://www.npmjs.com/package/corshttp://localhost:8080/api/app Nodeアプリが実行中です。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests は、ここで何が起こっているかについての詳細があります:あなたのappIDauthorizationkeyリクエストヘッダーは、OPTIONSを送信する前にCORSプリフライトGETリクエストを送信するようにブラウザーをトリガーしています。

そのOPTIONSリクエストを処理するには、cors npmパッケージをインストールして、 https://www.npmjs.com/package/cors#enabling-cors-の指示に従います。 pre-flight 設定するには:

var express = require('express')
  , cors = require('cors')
  , app = express();
app.options('*', cors()); // include before other routes
app.listen(80, function(){
  console.log('CORS-enabled web server listening on port 80');
});
1
sideshowbarker

受け入れられた答えは私に解決策を私に与えます、私はnodeJSバックエンドを使用していませんが、php-fpmでプレーンなNginxを使用しています。

しかし、答えはカスタムヘッダーを含むリクエストが常に最初にOPTIONSリクエストを実行して、設定されたヘッダー名の受け入れを確認する方法を説明しています。これがないと、my PHPコードがヒットし、認証が失敗し、結果として403コードが返されます。これは、使用されるコンテンツとリクエストメソッドでヘッダーが存在しないためです。

これは私がそれを機能させるためにNginxホストに追加したものです:

location ~ \.php$ {
             add_header 'Access-Control-Allow-Origin' "*";
             add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT';
             add_header 'Access-Control-Allow-Headers' 'appID,authorizationkey';

             if ($request_method = 'OPTIONS') {
                return 204;
             }
}

私はそれが完璧とは程遠いことを知っていますが、今のところそれでうまくいきました。そして、私を正しい方向に向けてくれてありがとう。

3
Steven Bakker