前端跨域
什么是跨域
跨域指的是:浏览器不能执行其他网站的脚本,从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域。跨域是由浏览器的同源策略造成的,是浏览器施加的安全限制。a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,所进行的访问行动都是跨域的。
跨域原理
当发起跨域请求时,会卡在接口响应阶段,由于浏览器的同源策略,实际正常返回,但是不能被浏览器响应。
什么是同源策略
同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域;
http:// https:// 不是同源 a.com b.com 不是同源 a.com:80 a.com:8000 不是同源
同源策略详情(可以略过)
当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面
当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,
如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
同源策略是浏览器的行为,是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。
同源策略的优势
跨域解决方式
-
jsonp跨域 目前几乎不用
// 接口返回 router.get('/testA', function (req, res, next) { let { callback } = req.query res.send(callback+"('123')") }); // 发送请求 <script> window.callback = function (data) { alert(data) // 弹出123 } let script = document.createElement('script') script.src = `http://test.a.com:3333/testA?name=1&callback=callback` document.body.appendChild(script) </script> -
nginx反向代理
使用场景:将前端静态页面部署到nginx服务器上原理分析:
-
cors
** linux环境修改 /etc/hosts文件 ** 10.167.15.207 是本机ip,这里主要作用是模拟一个域名,只在本地生效
使用场景:服务端做跨域处理,前端无需修改
> DEMO 场景 使用两个express搭建的前端服务
> 使用jquery ajax发送前端请求
```
1. express 允许返回HTML
2. 创建html文件
//test.a.com
router.get('/testA', function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin',"*") // cors跨域处理
res.send({
name:'123'
});
});
//test.b.com
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.js"></script>
<script>
$.ajax({
url:'http://test.a.com:3333/testA',
method:'get',
success: function(res) {
console.log(res)
},
error: function(err){
console.log(err)
}
})
```
6. http-proxy
使用场景:中间层做代理,进行转发,跟nginx相同。
源的更改
满足某些限制条件的情况下,页面是可以修改它的源。脚本可以将 document.domain 的值设置为其当前域或其当前域的父域。如果将其设置为其当前域的父域,则这个较短的父域将用于后续源检查。
document.domain = "company.com";
源 == 域 / 子域和父域的关系
使用 document.domain 来允许子域安全访问其父域时,您需要在父域和子域中设置 document.domain 为相同的值。这是必要的,即使这样做只是将父域设置回其原始值。不这样做可能会导致权限错误。
换句话说:子域可以获取父域的请求头信息 (联合登录时可以利用同域来解决)
前端允许的跨域有~
- script
- link
- img
- video
- @font-face
- iframe