ShopOne / Shitforces

くそなぞなぞコンテストサイト
shitforces.vercel.app
MIT License
27 stars 13 forks source link

CORSの設定がわからない #185

Closed no-yan closed 3 years ago

no-yan commented 3 years ago

96のプルリク@sei40krを引き継いでモックAPIを作っています。

現在、APIサーバーを起動してクライアント側からサーバーを叩くタイミングで、通信ができていません。

現象

  1. 通信ができていない
  2. devtoolsのネットワークのエラーメッセージ:CORS ERROR
  3. エラーにホバーして出るメッセージ:Resourse Sharing error: Invalid Allow Credentials
  4. ブラウザからAPIのアドレスを閲覧すると、JSONを閲覧することができる
  5. => エラーはポート間の通信の問題, CORSの設定をすれば通信できると推測できる image

ブラウザの一般的な仕様として同一ドメインでもポート番号が違う場合、通信するために設定で許可しなけれいけない(CORS)ようです。どう設定すれば正しく通信できるでしょうか?現在は次の設定をためしています。

      headers: {
        'Access-Control-Allow-Origin': 'http://localhost:3000',
        withCredentials: true,
      },

確認方法

forkしたリポジトリから確認できます。

git clone https://github.com/noyanyan/Shitforces/tree/mock
git checkout mock
cd Shitforces/frontend
npm install
npm run startdev

モックAPI設定ファイルはfrontend/agreed.jsにあります。

sei40kr commented 3 years ago

@noyanyan すみません、そのやりかけのPRのことをすっかり忘れていました。 結論から言うと agreed-server の起動オプションに --cors をつけることによって、モックサーバのレスポンスヘッダに Access-Control-Allow-Origin: * が付与されます。 npm run start から起動すれば既にこのオプションつきで起動するようになっています。

ちなみにモックデータなんですが現状色々バグりまくってます (suman)

ShopOne commented 3 years ago

あまりフロント詳しくないのとagreedを使ったことがないので助言があまり出来ず…ごめんなさい こちらのプルリク を見る限り、 --cors のオプションをつける形に?

ShopOne commented 3 years ago

って被った どひ〜☝💦 @sei40kr さんありがとうございます。

no-yan commented 3 years ago

お二人ともありがとうございます。 ですが実はfork先でも--corsを追加していて、少なくともそれだけの問題ではない気がします。 https://github.com/noyanyan/Shitforces/blob/f3f83dc20c5c0f45cf54110e5a7512fa0e73626a/frontend/package.json#L15

また、Access-Control-Allow-Origin: *とすると、ワイルドカードは許可されていないとエラーが出ているはずです。windows/chromeの問題でしょうか? もう少し調べてみますので、なにかあれば教えて下さい。

sei40kr commented 3 years ago

なるほど、このPRでリクエストにクレデンシャルを含めるようになったのが原因かもしれません。 https://github.com/ShopOne/Shitforces/pull/119

XMLHttpRequest.withCredentials を true にするとオリジンの指定にワイルドカードが使えなくなるようです。 https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSNotSupportingCredentials

解決策として --cors の代わりに --default-response-headers "{ 'Access-Control-Allow-Origin': 'http://localhost:3000', 'Access-Control-Allow-Credentials': true }" とすると良さそうです。

no-yan commented 3 years ago

オプションを--default-response-headers "{ 'Access-Control-Allow-Origin': 'http://localhost:3000', 'Access-Control-Allow-Credentials': true }"に変更すると問題なくAPIを表示することができました。 2日ほど悩んでいたので、伺えてよかったです。ありがとうございます。

一方で、これをコマンド実行するためには引用符の三重ネストが必要になり、JSON5がパースできませんでした。 "start:mock-api": "agreed-server --path agreed.js --port 8080 --default-response-headers '{ \"Access-Control-Allow-Origin\": \"http://localhost:3000\", \"Access-Control-Allow-Credentials\": true }'" なにか解決策がなければ、CLI実行することになりそうです。

no-yan commented 3 years ago

上記のJSONがパースされない件、エスケープする対象を変えることで問題解決しました。 "start:mock-api": "agreed-server --path agreed.js --port 8080 --default-response-headers \"{ 'Access-Control-Allow-Origin': 'http://localhost:3000', 'Access-Control-Allow-Credentials': true }\"",

不思議ですね