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-face
The same-origin policy is by default, and other undesirable things (such as WebGL textures anddrawImage
Resources 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:
XHR example:
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):
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-cors
If you get the request from other sources, it will cause CORS problems.
All you need to do is make things go smoothly.cors
The 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:https://glitch.com/edit/#!/flavio-cors-client.
This is the Node.js Express server:https://glitch.com/edit/#!/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:
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: *
:
You need to configure the server to allow only one source service and block all other sources.
Use the samecors
Node library, the method is as follows:
const cors = require('cors')
const corsOptions = {
origin: ‘https://yourdomain.com’,
}
app.get(’/products/:id’, cors(corsOptions), (req, res, next) => {
//…
})
You can also provide more services:
const whitelist = ['http://example1.com', 'http://example2.com']
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. AllGET
The request belongs to this group.
alsosome POST
withHEAD
The same is true for requests.
POST
If 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:OPTIONS
Claim.
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
Origin: https://your-origin.comThe server will respond with something like this(irrelevant fields omitted):
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://your-origin.com
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETEWe 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())
Download my free JavaScript Beginner's Handbook
More browser tutorials:
- Some useful tricks available in HTML5
- How I made a CMS-based website work offline
- The Complete Guide to Progressive Web Apps
- The Fetch API
- The Push API Guide
- The Channel Messaging API
- Service Workers Tutorial
- The Cache API Guide
- The Notification API Guide
- Dive into IndexedDB
- The Selectors API: querySelector and querySelectorAll
- Efficiently load JavaScript with defer and async
- The Document Object Model (DOM)
- The Web Storage API: local storage and session storage
- Learn how HTTP Cookies work
- The History API
- The WebP Image Format
- XMLHttpRequest (XHR)
- An in-depth SVG tutorial
- What are Data URLs
- Roadmap to learn the Web Platform
- CORS, Cross-Origin Resource Sharing
- Web Workers
- The requestAnimationFrame() guide
- What is the Doctype
- Working with the DevTools Console and the Console API
- The Speech Synthesis API
- How to wait for the DOM ready event in plain JavaScript
- How to add a class to a DOM element
- How to loop over DOM elements from querySelectorAll
- How to remove a class from a DOM element
- How to check if a DOM element has a class
- How to change a DOM node value
- How to add a click event to a list of DOM elements returned from querySelectorAll
- WebRTC, the Real Time Web API
- How to get the scroll position of an element in JavaScript
- How to replace a DOM element
- How to only accept images in an input file field
- Why use a preview version of a browser?
- The Blob Object
- The File Object
- The FileReader Object
- The FileList Object
- ArrayBuffer
- ArrayBufferView
- The URL Object
- Typed Arrays
- The DataView Object
- The BroadcastChannel API
- The Streams API
- The FormData Object
- The Navigator Object
- How to use the Geolocation API
- How to use getUserMedia()
- How to use the Drag and Drop API
- How to work with scrolling on Web Pages
- Handling forms in JavaScript
- Keyboard events
- Mouse events
- Touch events
- How to remove all children from a DOM element
- How to create an HTML attribute using vanilla Javascript
- How to check if a checkbox is checked using JavaScript?
- How to copy to the clipboard using JavaScript
- How to disable a button using JavaScript
- How to make a page editable in the browser
- How to get query string values in JavaScript with URLSearchParams
- How to remove all CSS from a page at once
- How to use insertAdjacentHTML
- Safari, warn before quitting
- How to add an image to the DOM using JavaScript
- How to reset a form
- How to use Google Fonts