web-dev-qa-db-ja.com

着信Webhookの緩み:リクエストヘッダーフィールドContent-typeは、プリフライト応答のAccess-Control-Allow-Headersでは許可されていません

ブラウザのフェッチAPIを介してSlackメッセージを投稿しようとしています。

fetch('https://hooks.slack.com/services/xxx/xxx/xx', {
  method: 'post',
  headers: {
    'Accept': 'application/json, text/plain, */*',
    'Content-type': 'application/json'
  },
  body: JSON.stringify({text: 'Hi there'})
})
  .then(response => console.log)
  .catch(error => console.error);
};

次のエラーメッセージが表示されます。

Fetch API cannot load:
https://hooks.slack.com/services/xxxxxxx/xxxxx. 
Request header field Content-type is not allowed by Access-Control-Allow-Headers in preflight response.

何をすべきか?

14
abnormi

残念ながら、そのSlack APIエンドポイントは、フロントエンドJavaScriptコードからのクロスオリジンリクエストの処理で壊れているように見えます。つまり、CORSプリフライトOPTIONSリクエストを適切に処理しないため、唯一の解決策はContent-Typeヘッダーを省略します。

したがって、リクエストコードのheaders部分から以下を削除する必要があるようです。

'Content-type': 'application/json'

その'Content-type': 'application/json'部分は、ブラウザに CORSプリフライトOPTIONSリクエスト を実行するようにトリガーします。そのため、ブラウザでフロントエンドJavaScriptコードが実行しようとしているPOSTリクエストを送信できるようにするには、https://hooks.slack.com/services APIエンドポイントが、値にAccess-Control-Allow-Headersを含むContent-Type応答ヘッダーを返す必要があります。

ただし、そのエンドポイントはそのヘッダーを返さないため、プリフライトは失敗し、ブラウザはそこで停止します。

通常、フロントエンドJavaScriptからJSONを期待するAPIエンドポイントに投稿する場合、そのContent-Type: application/jsonヘッダーをリクエストに追加することは、まさにあなたがしなければならないことであり、すべきことです。ただし、この場合はそうではありません。特定のAPIエンドポイントが適切に処理しないためです。

11
sideshowbarker

axiosを使用していますが、同様の問題が発生しました。私にとってうまくいったのは、Content-Typeヘッダーをapplication/x-www-form-urlencodedに設定することです。このスレッドで見つかりました: https://github.com/axios/axios/issues/475 これは「単純なリクエスト」をトリガーするため、CORSプリフライトのトリガーを回避するようです。 https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests

HTH。

8
Alex Shyba