why
前回の記事で Next.ts プロジェクトをテンプレで作った。
今回は API を呼べるようにする。
Axios 入れて useEffect で呼ぶだけでは叩けなかった。
6h ほどハマったので、解決策を記事にしておく。
axios のインストール
npm i axios
axios を使うことで HTTP リクエストができる。
UseEffect について
初回起動時に API を叩くように。
https://masa-engineer-blog.com/react-hook-useeffect/
第 2 引数がないと初回のみ動く
第 2 引数があると第 2 引数の更新時のみ動く
axios.create で GET リクエストをする
Home で
const axiosInstance = axios.create({ baseURL: "http://localhost:8080", headers: { 'Content-Type': 'application/json', }, })
- ベースの URL
- コンテンツタイプが JSON
ということを指定してインスタンスを作る
const getHeardOn = async () => { console.log("getHeardOn"); await axiosInstance .get(`/heard-on`) .then((response)=>{ setHeardOn(()=> response.data) }) .catch((e) =>{ console.log(`Error: ${e}`); }) }
次にインスタンスを使って
/heard-on に GET リクエストをする。
/heard-one は person-api で作ったエンドポイント。
useEffect で初回ロード時に呼び出す
useEffect(() => { console.log("loaded"); getHeardOn() console.log(heardOn); })
初回ロード時に getHeardOn を呼び出すようにする。
Access to XMLHttpRequest at 'http://localhost:8080/heard-on' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
localhost 3000 からのリクエストが
CORS によって弾かれた。
Access-Control-Allow-Origin
というヘッダーがリクエストのリソースに存在しない
とエラーが出た。
Access-Control-Allow-Origin をヘッダーに追加して送信に失敗
https://stackoverflow.com/questions/45975135/access-control-origin-header-error-using-axios
この記事を参考にして
const axiosInstance = axios.create({ baseURL: "http://localhost:8080", headers: { 'Content-Type': 'application/json', "Access-Control-Allow-Origin": "*", }, })
Access-Control-Allow-Origin: *
で
アクセスを許可する元:全て
にしたヘッダーを作ってリクエストした。
Access to XMLHttpRequest at 'http://localhost:8080/heard-on' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
kurab さんのにている記事を見つけたが少し違う。
やはり 'Access-Control-Allow-Origin' がついてないと怒られている。
axios インスタンスにつけるだけではダメなようだ。
next config の rewrite でローカルに送っている体にする
next.config.js
/** @type {import('next').NextConfig} */ const nextConfig = { async rewrites() { return [ { source: '/(.*)', destination: 'http://localhost:8080', }, ] }, }; module.exports = nextConfig
これで baseURL なしで、
デフォルトの localhost 3000 に送るコードが
到着地の localhost8080 に書き換わって送信される。
index.tsx
const axiosInstance = axios.create({ // baseURL: "http://localhost:8080", headers: { 'Content-Type': 'application/json', }, })
なので baseURL を外した。これで 8080 に送信できる。
実際に person-api と person-web を動かすと
上記のレスポンスで
これで解決した。
rewrite の詳細
https://nextjs-ja-translation-docs.vercel.app/docs/api-reference/next.config.js/rewrites
公式を見ると、
rewrite / source, destination は
proxy として mask するとある
/ へのリクエストを /about に変えて送るものだと解釈した。
なのでこの rewrite と proxy を使う。
localhost 3000 にリクエストさせるように見せる。
実際は localhost 8080 にリクエストさせる。
Next からは localhost 3000 の自分自身に送るように見える。
なので CORS エラーが出ない。
以上。
Top comments (0)