CORS, cross-domain resource sharing

Introduction to cross-domain resource sharing, a method that enables the client and server to communicate even if they are not in the same domain

A JavaScript application running in a browser can usually only access HTTP resources on the same domain (source) that it serves.

Images or scripts/styles can always be loaded, butXHRwithBring itUnless the server implements a method that allows the connection, the call to another server will fail.

This method is called CORS,Cross-domain resource sharing.

Also use the following way to load web fonts@font-faceThe same-origin policy is by default, and other undesirable things (such as WebGL textures anddrawImageResources loaded in the Canvas API).

One very important thing that requires CORS isES module, Recently introduced in modern browsers.

If you have not set a CORS policyOn the serverAllow service to third-party sources, the request will fail.

Get examples:

Fetch failed because of CORS policy

XHR example:

XHR request failed because of CORS policy

Cross-domain resources will fail in the following situations:

  • anotherfield
  • anotherSubdomains
  • anotherport
  • anotherprotocol

And it exists to ensure your safety to prevent malicious users from taking advantage ofnetwork platform.

However, if you control both the server and the client, there are good reasons for them to communicate with each other.

how is it?

It depends on your server-side stack.

Browser support

Pretty good (basically everything except IE <10):

CORS browser support

Express example

If you use Node.js and Express as the framework, please useCORS middleware package.

This is a simple implementation of ExpressNode.jsserver:

const express = require('express')
const app = express()

app.get(’/without-cors’, (req, res, next) => { res.json({ msg: ‘😞 no CORS, no party!’ }) })

const server = app.listen(3000, () => { console.log(‘Listening on port %s’, server.address().port) })

If you hit/without-corsIf you get the request from other sources, it will cause CORS problems.

All you need to do is make things go smoothly.corsThe package linked above, and pass it as a middleware function to the endpoint request handler:

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

app.get(’/with-cors’, cors(), (req, res, next) => { res.json({ msg: ‘WHOAH with CORS it works! 🔝 🎉’ }) })

/* the rest of the app */

I made a simple Glitch example, and here is its code:!/flavio-cors-client.

This is the Node.js Express server:!/flaviocopes-cors-example-express

Note that because the CORS header still cannot be processed correctly, you still receive the failed request, as you can see in the "Network" panel, where you can find the message sent by the server:

No response from CORS

Only allow certain sources

However, this example has a problem: the server will accept any request as a cross-domain.

As you can see in the "Network" panel, the passed request has a response headeraccess-control-allow-origin: *:

The CORS response header

You need to configure the server to allow only one source service and block all other sources.

Use the samecorsNode library, the method is as follows:

const cors = require('cors')

const corsOptions = { origin:, }

app.get(’/products/:id’, cors(corsOptions), (req, res, next) => { //… })

You can also provide more services:

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

Before the flight

Some requests are handled in a "simple" way. AllGETThe request belongs to this group.

alsosome POSTwithHEADThe same is true for requests.

POSTIf the request meets the requirements for using Content-Type, the request also belongs to this group

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

All other requests must go through a pre-approval stage called a pre-check. The browser determines whether it is authorized to perform the operation by issuing the following command:OPTIONSClaim.

The preflight request contains some headers, which the server will use to check permissions (ignoring irrelevant fields):

OPTIONS /the/resource/you/request
Access-Control-Request-Method: POST
Access-Control-Request-Headers: origin, x-requested-with, accept

The server will respond with something like this(irrelevant fields omitted):

HTTP/1.1 200 OK
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE

We checked for POST, but the server tells us we can also issue other HTTP request types for that particular resource.

Following the Node.js Express example above, the server must also handle the OPTIONS request:

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

//allow OPTIONS on just one resource app.options(’/the/resource/you/request’, cors())

//allow OPTIONS on all resources app.options(’*’, cors())

More browser tutorials: