一、nginx允许跨域
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS always;
add_header Access-Control-Allow-Credentials true always;
add_header Access-Control-Allow-Headers * always;
#处理预检请求
add_header Access-Control-Max-Age 6000 always;
if ($request_method = 'OPTIONS') {
return 204;
}
注意点
1、请求携带cookies
1、同域名下发送ajax请求,请求中默认会携带cookie
2、ajax在发送跨域请求时,默认情况下是不会携带cookie的
3、ajax在发送跨域请求时如果想携带cookie,必须将请求对象的withcredentials属性设置为true。
4、此时服务端的响应头Access-Control-Allow-Origin不能为*(星号)了,必须是白名单样式,也就是必须设置允许哪些url才能访问,如:
Access-Control-Allow-Origin: api.bob.com
5、除了对响应头Access-Control-Allow-Origin的设置,还必须设置另外一个响应头:Access-Control-Allow-Credentials:true。
2、withcredentials属性设置为true无效
在chrome 80版本之后,谷歌把cookie的SameSite属性,从None改成了Lax。这时候,会导致cookie因为跨站而导致不会自动带上!
所以需要后台在请求返回的时候 添加设置SiteSame 属性为 None 。
response.setHeader("Set-Cookie", "SameSite=None;Secure;JSESSIONID=xxx");
二、前端处理预检请求
后的未对OPTIONS预检/请求添加判断处理时,需要前端控制不发送预检请求处理如下:
//使用FormData参数格式 + axios的data字段
//使用formData发送请求时,axios不会预先发送option请求,直接只有一个post请求
let formData = new FormData();
formData.append('token', myToken);
axios({
method: 'post',
url: myUrl,
data: formData,
})
预检请求概念
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)
"预检"请求用的请求方法是OPTIONS,表示这个请求是用来询问的。头信息里面,关键字段是Origin,表示请求来自哪个源
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错
除了Origin字段,"预检"请求的头信息包括两个特殊字段:
Access-Control-Request-Method:该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法
Access-Control-Request-Headers:该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段
简单请求
请求方法是以下三种方法之一:
HEAD
GET
POST
Content-Type: (仅当POST方法的Content-Type值等于下列之一才算做简单需求)
text/plain
multipart/form-data
application/x-www-form-urlencoded
非简单请求
请求方法不是GET/HEAD/POST
POST请求的Content-Type并非application/x-www-form-urlencoded, multipart/form-data, 或text/plain
请求设置了自定义的header字段
三、无nginx时java处理
四、axios跨域请求
axios
.request({
url: '/api/common/operator/getInfo',
method: 'post', // 默认值
baseURL: 'https://192.168.6.120/',
timeout: 10000,
withcredentials: true,
data: {
test: 'test'
}
})
.then((response) => {
// 处理成功情况
console.log(response)
})
.catch((error) => {
// 处理错误情况
console.log(error)
})