#はじめに
APIサービスを構築する際に、Postmanなどのツールでは正常にアクセスできますが、
ブラウザからアクセスすると、エラーになる場合があります。
それはCORS(Cross-Origin Resource Sharing)対応をしていない可能性があります。
なぜなら、サイトのドメインとAPIサービスのドメインが違う場合は
先にoptionsメソッドで問い合わせをします。許可する場合のみ実際のAPIを通信します。
※同じドメインの場合はCORSの対応は要らないです。
#express.jsのcors対応
##方法1. optionsメソッドを実装
const app = express()
const allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
res.header(
'Access-Control-Allow-Headers',
'Content-Type, Authorization, access_token'
)
// intercept OPTIONS method
if ('OPTIONS' === req.method) {
res.send(200)
} else {
next()
}
}
app.use(allowCrossDomain)
##方法2. cors middlewareを利用
corsインストール
npm install cors
###すべてのAPIをCORS許可したい場合
const express = require('express')
const cors = require('cors')
const app = express()
app.use(cors())
app.get('/user/:userId', function (req, res, next) {
res.json({result: '任意のオリジンからすべてのAPIがアクセスOK'})
})
###個別のAPIをCORS許可したい場合
const express = require('express')
const cors = require('cors')
const app = express()
app.get('/user/:userId', cors(), function (req, res, next) {
res.json({result: '任意のオリジンからこのAPIのみアクセスOK'})
})
###CORSのオプション設定
設定可能なオプション:origin、methods、allowedHeaders、exposedHeaders、credentials、maxAge、preflightContinue、optionsSuccessStatus
設定例:
const express = require('express')
const cors = require('cors')
const app = express()
const corsOptions = {
origin: 'http://example.com',
optionsSuccessStatus: 200
}
app.get('/user/:userId', cors(corsOptions), function (req, res, next) {
res.json({msg: 'example.comからのアクセスのみ許可'})
})
#Vue.jsはproxy設定でCORSエラー回避
ローカル開発にてVue.jsとAPIサービスは違うポートで動作すると思います。
Apache,Nginxなどのサービスを経由していない場合は、
CORS問題がありますのでCORS対応が必要となります。
ただし、STG・本番はCORS対応は不要な場合が多いので、ローカルではCORSコードを追加するとよろしくないです。
Vue.jsはproxyの設定でCORS問題を回避できます。vue.config.jsに下記のように設定
module.exports = {
devServer:{
proxy:{
'^/api':{
target: 'http://localhost:3001',
ws: true,
secure: false
}
}
}
}
#ヘッダーパラメータ名の注意点
ヘッダーのパラメータ名は小文字になる場合があります。
通信する際に{accessToken:'xxxxxx'}のヘッダーを設定して通信すると、
req.headers.accessToken
では取得できず、req.headers.accesstoken
なら取得できます。
ですので、ヘッダーのキー名はキャメルではなく、単語間を「_」で連結したほうがよいと思います。
参考記事:https://expressjs.com/en/resources/middleware/cors.html
以上