Coder Social home page Coder Social logo

cors's Introduction

Cloned from NPM Version, Test on window.

CORS is a node.js package for providing a Connect/Express middleware that can be used to enable CORS with various options.

Installation

This is a Node.js module available through the npm registry. Installation is done using the npm install command:

> npm install cors

Test

\cors>npm run test


> [email protected] test \cors
> npm run lint && nyc --reporter=html --reporter=text mocha --require test/support/env


> [email protected] lint \cors
> eslint lib test


  error response
    √ 500 (80ms)
    √ 401
    √ 404

  example app(s)
    simple methods
      √ GET works
      √ HEAD works
      √ POST works
    complex methods
      √ OPTIONS works
      √ DELETE works

  issue  #2
    √ OPTIONS works
    √ POST works

  cors
    √ does not alter `options` configuration object
    √ passes control to next middleware
    √ shortcircuits preflight requests
    √ can configure preflight success response status code
    √ doesn't shortcircuit preflight requests with preflightContinue option
    √ normalizes method names
    √ includes Content-Length response header
    √ no options enables default CORS to all origins
    √ OPTION call with no options enables default CORS to all origins and methods
    passing static options
      √ overrides defaults
      √ matches request origin against regexp
      √ matches request origin against array of origin checks
      √ doesn't match request origin against array of invalid origin checks
      √ origin of false disables cors
      √ can override origin
      √ includes Vary header for specific origins
      √ appends to an existing Vary header
      √ origin defaults to *
      √ specifying true for origin reflects requesting origin
      √ should allow origin when callback returns true
      √ should not allow origin when callback returns false
      √ should not override options.origin callback
      √ can override methods
      √ methods defaults to GET, HEAD, PUT, PATCH, POST, DELETE
      √ can specify allowed headers as array
      √ can specify allowed headers as string
      √ specifying an empty list or string of allowed headers will result in no response header for allowed headers
      √ if no allowed headers are specified, defaults to requested allowed headers
      √ can specify exposed headers as array
      √ can specify exposed headers as string
      √ specifying an empty list or string of exposed headers will result in no response header for exposed headers
      √ includes credentials if explicitly enabled
      √ does not includes credentials unless explicitly enabled
      √ includes maxAge when specified
      √ includes maxAge when specified and equals to zero
      √ does not includes maxAge unless specified
    passing a function to build options
      √ handles options specified via callback
      √ handles options specified via callback for preflight
      √ handles error specified via callback


  49 passing (273ms)

  ----------|----------|----------|----------|----------|-------------------|
  File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
  ----------|----------|----------|----------|----------|-------------------|
  All files |        0 |        0 |        0 |        0 |                   |
  ----------|----------|----------|----------|----------|-------------------|


\cors\.eslintrc.yml

root: true
env:
  node: true
extends: 'eslint:recommended'
rules:
  array-bracket-spacing:  [ 2, 'never']
  block-spacing:           [ 2, 'always' ]
  brace-style:             [ 2, '1tbs', { 'allowSingleLine': false }]
  comma-style:             [ 2, 'last' ]
  curly:                   [ 2, 'all' ]
  dot-location:            [ 2, 'property' ]
  global-require:          0
  indent:                  [ 2, 2, { 'SwitchCase': 1 }]
  linebreak-style:         [ 0, 'windows' ]
  multiline-comment-style: [ 2, 'starred-block' ]
  no-multiple-empty-lines: [ 2, { 'max': 1, 'maxBOF': 0, 'maxEOF': 1 }]
  no-param-reassign:       1
  no-trailing-spaces:      [ 2, { 'skipBlankLines': false, 'ignoreComments': false }]
  no-undef:                [ 1, { 'typeof': true }]
  no-unused-vars:          [ 1, { 'vars': 'local', 'args': 'after-used', 'ignoreRestSiblings': false }]
  object-curly-spacing:    [ 2, 'always', { 'objectsInObjects': false }]
  quotes:                  [ 2, 'single']
  semi:                    [ 2, 'always' ]
  semi-spacing:            [ 2, { 'before': false, 'after': true }]
  space-before-blocks:     [ 2, 'always' ]
  space-before-function-paren: [ 2, { 'anonymous': 'always', 'named': 'never', 'asyncArrow': 'always' }]
  spaced-comment:          [ 2, "always", {
    "line": {
      "markers": ["/"],
      "exceptions": ["-", "+"]
    },
    "block": {
      "markers": ["!"],
      "exceptions": ["*"],
      "balanced": true
    }
  }]
  space-in-parens:         [ 2, 'never']

Configuring CORS

var express = require('express')
var cors = require('cors')
var app = express()

var corsOptions = {
  origin: 'http://example.com',
  optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}

app.get('/products/:id', cors(corsOptions), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for only example.com.'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

Configuring CORS w/ Dynamic Origin

var express = require('express')
var cors = require('cors')
var app = express()

var whitelist = ['http://example1.com', 'http://example2.com']
var corsOptions = {
  origin: function (origin, callback) {
    if (whitelist.indexOf(origin) !== -1) {
      callback(null, true)
    } else {
      callback(new Error('Not allowed by CORS'))
    }
  }
}

app.get('/products/:id', cors(corsOptions), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a whitelisted domain.'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

If you do not want to block REST tools or server-to-server requests, add a !origin check in the origin function like so:

var corsOptions = {
  origin: function (origin, callback) {
    if (whitelist.indexOf(origin) !== -1 || !origin) {
      callback(null, true)
    } else {
      callback(new Error('Not allowed by CORS'))
    }
  }
}

Enabling CORS Pre-Flight

Certain CORS requests are considered 'complex' and require an initial OPTIONS request (called the "pre-flight request"). An example of a 'complex' CORS request is one that uses an HTTP verb other than GET/HEAD/POST (such as DELETE) or that uses custom headers. To enable pre-flighting, you must add a new OPTIONS handler for the route you want to support:

var express = require('express')
var cors = require('cors')
var app = express()

app.options('/products/:id', cors()) // enable pre-flight request for DELETE request
app.del('/products/:id', cors(), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for all origins!'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

You can also enable pre-flight across-the-board like so:

app.options('*', cors()) // include before other routes

Configuring CORS Asynchronously

var express = require('express')
var cors = require('cors')
var app = express()

var whitelist = ['http://example1.com', 'http://example2.com']
var corsOptionsDelegate = function (req, callback) {
  var corsOptions;
  if (whitelist.indexOf(req.header('Origin')) !== -1) {
    corsOptions = { origin: true } // reflect (enable) the requested origin in the CORS response
  } else {
    corsOptions = { origin: false } // disable CORS for this request
  }
  callback(null, corsOptions) // callback expects two parameters: error and options
}

app.get('/products/:id', cors(corsOptionsDelegate), function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for a whitelisted domain.'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

Configuration Options

  • origin: Configures the Access-Control-Allow-Origin CORS header. Possible values:
    • Boolean - set origin to true to reflect the request origin, as defined by req.header('Origin'), or set it to false to disable CORS.
    • String - set origin to a specific origin. For example if you set it to "http://example.com" only requests from "http://example.com" will be allowed.
    • RegExp - set origin to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern /example\.com$/ will reflect any request that is coming from an origin ending with "example.com".
    • Array - set origin to an array of valid origins. Each origin can be a String or a RegExp. For example ["http://example1.com", /\.example2\.com$/] will accept any request from "http://example1.com" or from a subdomain of "example2.com".
    • Function - set origin to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (which expects the signature err [object], allow [bool]) as the second.
  • methods: Configures the Access-Control-Allow-Methods CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: ['GET', 'PUT', 'POST']).
  • allowedHeaders: Configures the Access-Control-Allow-Headers CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: ['Content-Type', 'Authorization']). If not specified, defaults to reflecting the headers specified in the request's Access-Control-Request-Headers header.
  • exposedHeaders: Configures the Access-Control-Expose-Headers CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: ['Content-Range', 'X-Content-Range']). If not specified, no custom headers are exposed.
  • credentials: Configures the Access-Control-Allow-Credentials CORS header. Set to true to pass the header, otherwise it is omitted.
  • maxAge: Configures the Access-Control-Max-Age CORS header. Set to an integer to pass the header, otherwise it is omitted.
  • preflightContinue: Pass the CORS preflight response to the next handler.
  • optionsSuccessStatus: Provides a status code to use for successful OPTIONS requests, since some legacy browsers (IE11, various SmartTVs) choke on 204.

The default configuration is the equivalent of:

{
  "origin": "*",
  "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
  "preflightContinue": false,
  "optionsSuccessStatus": 204
}

For details on the effect of each CORS header, read this article on HTML5 Rocks.

Demo

A demo that illustrates CORS working (and not working) using jQuery is available here:

Code for that demo can be found here:

License

MIT License

Original Author

Troy Goode ([email protected])

cors's People

Contributors

bill1812 avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.