CORS エラー回避のためローカルのプロキシ経由で API アクセスする

副業で友人の LP 制作を手伝っている。

今回、某ベンダーが提供する API に LP からアクセスすることになった。ただ、普段はローカルで開発しており、ベンダーの API には CORS で弾かれてアクセスできない...。テスト環境はないし、API のベンダーに CORS の設定を変更してもらうとかもできない。

で、ちょっと調べた感じ、ローカルにプロキシを立てるのが手っ取り早そうだったので、それ経由で API アクセスする。

import express from 'express'
import fetch from 'node-fetch'
import cors from 'cors'

const app = express()
const port = 3000

app.use(cors())

app.get('/my-proxy', async (req, res) => {
    const targetUrl = req.query.url
    if (!targetUrl) {
        return res.status(400).send('Parameter not found')
    }
    try {
        const response = await fetch(targetUrl)
        const html = await response.text()
        res.send(html)
    } catch (error) {
        console.error(error)
        res.status(500).send('fetching failed')
    }
})

app.listen(port, () => {
    console.log(`Server is running at http://localhost:${port}`)
})

起動。

$ node server.js

使うときはこんな感じ。(fetch をラップしておく)

const PROXY = 'http://localhost:3000/my-proxy?url='

function _fetch(targetUrl) {
  return fetch(PROXY ? PROXY + encodeURIComponent(targetUrl) : targetUrl)
}

_fetch('https://example.com/api/v1/foo')
  .then(response => response.json())
  .then(data => {
    // ...省略
  })

あと、header を付けてアクセスしたい場合。(以下は Authorization ヘッダーを付ける例)

app.get('/my-proxy', async (req, res) => {
    const targetUrl = req.query.url
    const headers = new Headers({ 'Authorization': req.headers.authorization }) // ★
    if (!targetUrl) {
        return res.status(400).send('Parameter not found')
    }
    try {
        const response = await fetch(targetUrl, { headers: headers }) // ★
        const html = await response.text()
        res.send(html)
    } catch (error) {
        console.error(error)
        res.status(500).send('fetching failed')
    }
})

使うときはこんな感じ。

function _fetch(targetUrl) {
  return fetch(PROXY + encodeURIComponent(targetUrl), { headers: headers })
}

現場からは以上です。