Express.jsでAccess-Control-Allow-Originを設定しているのにCORSエラーが発生した

Vue.jsからExpressへPOSTリクエストを送信するとき、Access-Control-Allow-Originを設定しているにも関わらずCORSエラーが発生したので、その解決策をメモしておく。

WebセキュリティやHTTPにそもそも疎いため、特にpreflight requestについては別の機会に学び直したい。

ソースコード

app.post('/db_insert', async (req: Request, res: Response) => {

    // ブラウザを叩いても"test"が出力されないので、そもそもリクエストを受け取れていない?
    console.log("test");
    // 項目名
    const subject_name = req.body.subject_name;
    // 学習時間
    const used_time = req.body.used_time;

    const query = "INSERT INTO learning_list(subject_name, used_time) VALUES(?, ?)"
    const params = [subject_name, used_time] as any[];
    let con_res: any[] = []
    try {
        con_res = (await db_query(query, params, db_con)) as any[]
    } catch (err) {
        console.log(err)
    }
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:5173')
    res.send(con_res)
})
<script setup>
import axios from "axios";
import { reactive } from "vue";

const url2 = "http://localhost:3000/db_insert";

const insert_form = reactive({
    subject_name: "",
    used_time: ""
})

const insertData = async () => {
    let result = await axios.post(url2, {
        subject_name: insert_form.subject_name,
        used_time: insert_form.used_time
    });
};
</script>

<template>
    <p>データ登録</p>
    <form>
        項目名<input type="text" v-model="insert_form.subject_name" /><br>
        学習時間<input type="text" v-model="insert_form.used_time" />
        <input type="button" value="INSERT!" @click="insertData" />
    </form>
</template>

原因

Preflight Requestというリクエストが送信されているためにCORSエラーが発生していた。(画像からも読み取れる)

対策

ミドルウェアの「cors」を導入した。

app.use(cors({
    origin: 'http://localhost:5173',
    credentials: true,
    optionsSuccessStatus: 200
}))

app.post('/db_insert', async (req: Request, res: Response) => {

    // 項目名
    const subject_name = req.body.subject_name;
    // 学習時間
    const used_time = req.body.used_time

    const query = "INSERT INTO learning_list(subject_name, used_time) VALUES(?, ?)"
    const params = [subject_name, used_time] as any[];
    let con_res: any[] = []
    try {
        con_res = (await db_query(query, params, db_con)) as any[]
    } catch (err) {
        console.log(err)
    }
    res.send(con_res)
})

参考

preflight requestやミドルウェアcorsについては次のサイトを参考にした。