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)