前端跨域的几种常用解决方案

0 跨域

造成跨域是因为浏览器的同源策略,不允许js去请求不在同一个域下的资源,即使是localhost,这是防止XSS攻击的第一道防线(?)。(img标签除外,所以img也成了xss攻击的常用跳板方式)

1.jsonp

原理: script 标签不受同源策略的影响

需要后端接口返回一个回调函数,前端在回调函数做数据处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参并指定回调执行函数为onBack
script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack';
document.head.appendChild(script);
// 回调执行函数
function onBack(res) {
alert(JSON.stringify(res));
}
</script>
// 后端返回
// onBack({"status": true, "user": "admin"})

还能使用 iframe 或者 posrMessage 来解决跨域, 但是安全性不高。

2.CORS

普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置。
带cookie请求:前后端都需要设置字段,因为 cookie 需要设置域。

后端设置

1
2
3
4
5
6
// 跨域后台设置
res.writeHead(200, {
'Access-Control-Allow-Credentials': 'true', // 后端允许发送Cookie
'Access-Control-Allow-Origin': 'http://www.domain1.com', // 允许访问的域(协议+域名+端口)
'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly' // HttpOnly:脚本无法读取cookie
});

3.nginx 代理

跨域原理: 同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨越问题。

通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域登录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 81;
server_name www.domain1.com;
location / {
proxy_pass http://www.domain2.com:8080; #反向代理
proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie里域名
index index.html index.htm;
# 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用
add_header Access-Control-Allow-Origin http://www.domain1.com; #当前端只跨域不带cookie时,可为*
add_header Access-Control-Allow-Credentials true;
}
}