cors
2020 M12 20
简单请求和复杂请求
cors分为简单请求和复杂请求,对于简单请求的限制较少,对于复杂请求的限制较多。 对于简单请求,基本上设置一个响应头Access-Control-Allow-Origin足矣,不会发探测请求(options)。 而对于复杂请求,往往需要一些额外的响应头的处理,会发探测请求。 那简单请求和复杂请求是如何划分的呢?先看下什么是简单请求:
请求方法为以下3种:
HEAD、GET、POST
请求头为以下3种:
Accept 期望返回格式
Accept-Language 期望返回的语言
Content-Type 决定文件接收方如何解析
其中Content-Type只能是:text/plain、multipart/form-data 或 application/x-www-form-urlencoded
这也就意味着:application/json 不是简单请求
Accept-Language 期望返回的语言
Content-Type 决定文件接收方如何解析
其中Content-Type只能是:text/plain、multipart/form-data 或 application/x-www-form-urlencoded
这也就意味着:application/json 不是简单请求
除此之外的,都视为复杂请求
options
只有复杂请求会发送options请求
可使用Access-Control-Max-Age 设置options请求发送时间间隔 Access-Control-Max-Age: 600 (10分钟)
Access-Control-Max-Age表示Access-Control-Allow-Origin和Access-Control-Allow-Headers的缓存时长)
在 Firefox 中,上限是24小时 (即 86400 秒)。)
在 Chromium v76 之前, 上限是 10 分钟(即 600 秒)。)
从 Chromium v76 开始,上限是 2 小时(即 7200 秒)。)
Chromium 同时规定了一个默认值 5 秒。)
如果值为 -1,表示禁用缓存,则每次请求前都需要使用 OPTIONS 预检请求。
复杂请求的限制
对于复杂请求限制主要体现在两个方面:方法限制和请求头限制
对于前者,后端可通过设置Access-Control-Allow-Methods,允许指定方法跨域,多个值则用逗号隔开 'PUT,DELETE'
对于后者,后端可通过设置Access-Control-Allow-Headers,允许指定头跨域,多个值则用逗号隔开 'xxx,yyy'
对于前者,后端可通过设置Access-Control-Allow-Methods,允许指定方法跨域,多个值则用逗号隔开 'PUT,DELETE'
对于后者,后端可通过设置Access-Control-Allow-Headers,允许指定头跨域,多个值则用逗号隔开 'xxx,yyy'
跨域携带cookie
默认情况下,不论是fetch还是axios,都不会跨域携带cookie。
如果允许携带cookie,那后端设置的Access-Control-Allow-Origin和其他头的值不能是*,要具体指定
如果允许携带cookie,需要后端设置Access-Control-Allow-Credentials为true
如果允许携带cookie,那后端设置的Access-Control-Allow-Origin和其他头的值不能是*,要具体指定
如果允许携带cookie,需要后端设置Access-Control-Allow-Credentials为true
fetch默认会忽略cookie的发送
omit:默认值,忽略cookie的发送
same-origin:表示cookie只能同域发送,不能跨域发送
include:既可以同域发送,也可以跨域发送
same-origin:表示cookie只能同域发送,不能跨域发送
include:既可以同域发送,也可以跨域发送
fetch('http://localhost:3000/api/',{
headers:{
token:'xxx'
},
credentials: 'include'
}).then(res => {
return res.json()
}).then(res => {
console.log(res)
})
axios默认不允许跨域携带cookie
可通过设置:axios.defaults.withCredentials = true;改变
后端跨域设置
const app = new (require('koa'))
app.use((ctx) => {
// ctx.set('Access-Control-Allow-Origin', '*')
ctx.set('Access-Control-Allow-Origin', ctx.headers.origin)
ctx.set('Access-Control-Allow-Credentials',true)
// ctx.set('Access-Control-Allow-Headers', '*')
ctx.set('Access-Control-Allow-Headers', 'token')
// ctx.set('Access-Control-Allow-Methods', 'PUT,DELETE')
ctx.set('Access-Control-Allow-Methods', '*')
ctx.set('Access-Control-Max-Age', 60)//1分钟内不再发options请求
ctx.set('Set-Cookie', 'token=xxxyyyzzz')
ctx.body = { name: "tom" }
})
app.listen(3000, () => {
console.log('run server')
})