search
LoginSignup
110
Help us understand the problem. What are the problem?

posted at

updated at

express.jsのcors対応

はじめに

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

以上

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
110
Help us understand the problem. What are the problem?