以前に「Reactでaxios経由でAWS API Gatewayからデータ取得しようとする時にCORSでエラーになる」という記事を書きました。
最終的にGETではうまくいっていたのですが、AWS APIGateway+ LambdaをProxy統合で利用していた場合、POSTで同じようにaxiosでデータを取得しようとすると、再びCORSエラーが発生してしまいました。
そこで、今回はPOSTの場合の原因と対応方法について追加で調査しました。
1. POSTの場合のエラー内容
まずは、エラーの内容です。
XMLHttpRequest cannot load http://xxxxxx. Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
preflight responseが発生してエラーになってしまっているようです。
2. Preflight request とは?
Preflight request (プリフライトリクエスト)ですが、ブラウザのCORS仕様の一部で、実際のリクエストを送信する前に、そのリクエストが安全かどうか、前もってOPTIONS
リクエストを送信して確かめる仕様です。
このOptionリクエストがCORSエラーとなってしまうのです。
Preflight requestは「単純リクエスト」でない場合に発生します。
細かいところは割愛しますが、「単純リクエスト」は以下の様に定義されます。
GET
,HEAD
,POST
のうちいずれか- ヘッダーに含まれるのが以下のうちいずれか
- ユーザーエージェントによって自動的に設定されたヘッダー
- Accept
- Accept-Language
- Content-Language
- Content-Type
- Content-Typeのヘッダーが以下のうちいずれか
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
- リクエストに使用されるどの XMLHttpRequestUpload にもイベントリスナーが登録されていないこと。
- リクエストに ReadableStream オブジェクトが使用されていないこと。
3. POSTでCORSエラーの原因
どうもaxiosでPOSTを実行しようとすると、Content-Typeが「application/json」として通信が発生しているようです。
つまり、上の定義でいうところの「Content-Typeのヘッダーが以下のうちいずれか」にマッチしなくなってPreflight requestが発生しています。
4. 対応方法
axiosでリクエストする際のヘッダーに「”Content-type”: “text/plain”」として指定してあげます。
こんな感じで引数にheaderの値を指定します。
const onClickGet = () => {
console.log(urlAPI)
axios.post<[]>(urlAPI + "/asin",
datas,
{ headers: { "Content-type": "text/plain" } }
)
.then((res) => {
console.log(res.data);
setStatus(res.data);
}).catch((error) => {
console.log(error);
});
}
そうすることで、 Preflight request が発生しなくなって、正常にアクセスできるようになりました。
Pythonのオススメ勉強方法
私がオススメするPython初心者向けの最初に購入すべき書籍は「シリコンバレー一流プログラマーが教える Pythonプロフェッショナル大全」です。
シリコンバレー一流プログラマーが教える Pythonプロフェッショナル大全
この書籍は実際にシリコンバレーの一流エンジニアとして活躍している酒井潤さんが書いた本です。
内容も初心者から上級者までまとめられており、各Lessonも長すぎずに分かりやすくまとめられているので、初心者の方にもおすすめです。
シリコンバレー一流プログラマーが教える Pythonプロフェッショナル大全
今回は以上となります。
コメント