web-dev-qa-db-ja.com

クライアント側でAccess-Control-Allow-Originを設定した後でもCORSエラー

webpack-simpleオプションで生成されたVueアプリケーションがあります。 GEThttps://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=enにリクエストしようとしていますが、エラーが発生します:

XMLHttpRequestはhttps://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=enをロードできません。プリフライトリクエストへの応答がアクセス制御チェックに合格しません。リクエストされたリソースに「Access-Control-Allow-Origin」ヘッダーがありません。したがって、Origin 'http://127.0.0.1:8080'はアクセスを許可されていません。

私はvue-resourceを使用しており、次を追加しました:

Vue.http.headers.common['Access-Control-Allow-Origin'] = '*'

それは効果がありません。

webpack.config.jsdevServerオプションにもこれを追加しました。

devServer: {
  historyApiFallback: true,
  noInfo: true,
  headers: {
    "Access-Control-Allow-Origin": "*"
  }
}

それも問題を解決していません。エラーメッセージは同じままです。

これを解決するにはどうすればいいですか?

10
wrahim

Access-Control-Allow-Originは、リクエストの送信先サーバーが送信する必要があるresponseヘッダーです。

ただし、https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=enAccess-Control-Allow-Originヘッダーを送信しないため、代わりにプロキシ経由でリクエストを行う必要があります。そのためには、代わりにこのURLを使用するようにフロントエンドJavaScriptコードを変更します。

https://cors-anywhere.herokuapp.com/https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en

それを試してみると、フロントエンドのコードは期待通りに機能します。ただし、最初にこれも削除してください:

Vue.http.headers.common['Access-Control-Allow-Origin'] = '*'

つまり、Access-Control-Allow-Originヘッダーをrequestにリクエストヘッダーとして追加しています。ただし、上記のように、Access-Control-Allow-Originresponseヘッダーです。したがって、リクエストにAccess-Control-Allow-Originを追加することで得られる唯一の効果は、OPTIONSを送信するのではなく、ブラウザーが CORSプリフライトGETリクエスト を送信するようトリガーすることです。

また、これを削除することもできます:

headers: {
  "Access-Control-Allow-Origin": "*"
}

しているように見えるすべては、あなたのサーバーバックエンドからの応答にAccess-Control-Allow-Origin応答ヘッダーを追加することです。ただし、フロントエンドコードが行うリクエストは、サーバーのバックエンドではなく、https://api.forismatic.com/に送信されます。

とにかく、https://cors-anywhere.herokuapp.com/https://api.forismatic.com/… URLは、リクエストをhttps://cors-anywhere.herokuapp.comに送信するオープン/パブリックCORSプロキシであるhttps://api.forismatic.com/api/1.0/?method=getQuote…にリクエストを送信します。

そして、そのプロキシが応答を取得すると、それを取得してAccess-Control-Allow-Origin応答ヘッダーを追加し、それを応答として要求元のフロントエンドコードに渡します。

Access-Control-Allow-Origin応答ヘッダーを持つその応答はブラウザに表示されるものであるため、ブラウザが表示しているエラーメッセージは消え、ブラウザはフロントエンドJavaScriptコードが応答にアクセスすることを許可します。

または、 https://github.com/Rob--W/cors-anywhere/ などのコードを使用して、独自のプロキシを設定します。

プロキシが必要な理由は、https://api.forismatic.com/api/1.0/?method=getQuote…自体がAccess-Control-Allow-Origin応答ヘッダーを送信しないため、ブラウザはフロントエンドJavaScriptコードがそのサーバーのクロスオリジンからの応答にアクセスすることを拒否するためです。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS に詳細があります。

15
sideshowbarker