CORS全称
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源(协议 + 域名 + 端口)服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
CORS使用限制
CORS 需要浏览器和后端同时支持。
IE 8 和 9 需要通过 XDomainRequest 来实现。
CORS实现方式
服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。
CORS基本流程
浏览器将CORS请求分为两类:简单请求(simple request)和非简单请求(not-so-simple request)
简单请求,只需要在头信息之中增加一个Origin字段。
非简单请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
只要同时满足以下两大条件,就属于简单请求。
- 请求方法是以下三种方法之一:
- GET
- POST
- HEAD
- 请求header里面:
- 无自定义头
- Content-Type只限于以下三个值
application/x-www-form-urlencoded
multipart/form-data
text/plain
CORS示例
前端
let xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.open('PUT', 'http://localhost:8090/testCors', true);
// xhr.open('get', 'http://localhost:8090/testCors', true);
xhr.setRequestHeader('name', 'Lee');
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
console.log(xhr.response, xhr.getResponseHeader('name')); // put/get, zhang
}
}
};
xhr.send();
后端(以nodejs为例)
const express = require('express');
const app = express();
const whiteList = ['http://localhost:1820'];
app.use((req, res, next) => {
const origin = req.headers.origin;
if (whiteList.includes(origin)) {
// 设置哪个源可以访问我
res.setHeader('Access-Control-Allow-Origin', origin);
// 允许携带哪个头访问我
res.setHeader('Access-Control-Allow-Headers', 'name');
// 允许哪个方法访问我
res.setHeader('Access-Control-Allow-Methods', 'PUT');
// 允许携带cookie
res.setHeader('Access-Control-Allow-Credentials', true);
// 预检的存活时间
res.setHeader('Access-Control-Max-Age', 6);
// 允许返回的头
res.setHeader('Access-Control-Expose-Headers', 'name');
}
next();
});
app.put('/testCors', (req, res) => {
console.log(req.headers);
// 返回一个后台的响应头
res.setHeader('name', 'zhang');
res.end('put');
});
app.get('/testCors', (req, res) => {
console.log(req.headers);
res.end('get');
});
app.listen(8090);