同源策略
同源策略是一个重要的安全策略,它能帮助阻隔恶意文档,减少可能被攻击的媒介。
如果两个 URL 的 protocol、port (如果有指定的话)和 host 都相同的话,则这两个 URL 是同源。
| URL | 结果 | 原因 |
|---|---|---|
http://store.company.com/dir2/other.html | 同源 | 只有路径不同 |
http://store.company.com/dir/inner/another.html | 同源 | 只有路径不同 |
https://store.company.com/secure.html | 失败 | 协议不同 |
http://store.company.com:81/dir/etc.html | 失败 | 端口不同 ( http:// 默认端口是80) |
http://news.company.com/dir/other.html | 失败 | 主机不同 |
跨域资源共享
-
CORS (Cross-Origin Resource Sharing,跨域资源共享)是一个系统,它由一系列传输的HTTP头组成,这些HTTP头决定浏览器是否阻止前端 JavaScript 代码获取跨域请求的响应。
-
浏览器的同源安全策略默认会阻止网页"跨域”获取资源。但如果接口服务器配置了CORS相关的HTTP响应头, 就可以解除浏览器端的跨域访问限制。
-
CORS 主要在服务器端进行配置。客户端浏览器无须做任何额外的配置,即可请求开启了CORS的接口
请求分类
客户端在请求CORS接口时,根据请求方式和请求头的不同,可以将CORS的请求分为两大类
简单请求
同时满足以下两大条件的请求,就属于简单请求:
- 请求方式:
GET、POST、HEAD三者之一 - HTTP头部信息为以下字段:
- 无自定义头部字段
AcceptAccept-LanguageContent-LanguageDPRDownlinkSave-DataViewport-WidthWidthContent-Type(值仅限于text/plain、multipart/,form-data、application/x-www-form-urlencoded三者之一)
预检请求
只要符合以下任何一个条件的请求,都需要进行预检请求:
- 请求方式为
GET、POST、HEAD之外的请求Method类型 - 请求头中包含自定义头部字段
- 向服务器发送了
application/json格式的数据 在浏览器与服务器正式通信之前,浏览器会先发送 OPTIONS 请求进行预检,以获知服务器是否允许该实际请求,所以这一次的OPTIONS 请求称为“预检请求”。服务器成功响应预检请求后,才会发送真正的请求,并且携带真实数据。
响应头部
Access-Control-Allow-Origin
指示请求的资源能共享给哪些域。
app.all('*', function (req, res, next) {
//允许所有来源访问
res.header('Access-Control-Allow-Origin', '*')
// 允许指定 URI ,服务器指定只允许https://developer.mozilla.org的请求
// https://developer.mozilla.org 可以接受到此服务器的响应
res.header('Access-Control-Allow-Origin': https://developer.mozilla.org)
next()
})
Access-Control-Allow-Headers
- 默认情况下,CORS仅支持客户端向服务器发送简单请求,如果客户端向服务器发送了额外的请求头信息,则需要在服务器端,通过
Access-Control-Alow-Headers对额外的请求头进行声明,否则这次请求会失败! - 会被用于预检请求中,预检请求会想服务器发送俩个请求,第一个请求是
options请求,判断是否可以进行跨域资源共享
// 创建ajax对象
let xhr = new XMLHttpRequest()
// ajax对象以什么方式对哪里发送请求
xhr.open('post', 'http://127.0.0.1:8080')
// 设置请求参数类型,application/json会产生预检请求
xhr.setRequestHeader('Content-Type','application/json')
// 参数必须在send函数中发出
xhr.send(JSON.stringify(params))
//设置预检请求 第二步接收
app.options('/',(req,res)=>{
//允许post请求使用 application/json
res.header("Access-Control-Allow-Headers", "Content-Type");
})
// 设置post请求 第二步接收
app.post('/',(req,res)=>{
console.log('hello post');
res.send('post 成功')
});
Access-Control-Allow-Methods
默认情况下,CORS 仅支持客户端发起 GET、POST、HEAD 请求。 如果客户端希望通过 PUT、DELETE 等方式请求服务器的资源,则需要在服务器端,通过 Access-Control-Alow-Methods 来指明实际请求所允许使用的HTTP方法。
//只允许POST、GET、DELETE、HEAD请求方法
res.setHeader('Access-Control-Allow-Methods','POST,GET,DELETE,HEAD')
//允许所有的HTTP清求方法
res.setHeader('Access-Control-Allow-Methods','*')