跨域解决方案处理
文章目录
- 首先了解什么是跨域
- 1. 什么是跨域?
- 2. 源是什么?
- 3. 同源策略又是什么?
- 4. 同源请求与非同源请求
- 5. 浏览器对跨域请求的限制有哪些?
- 解决跨域方案
- 1. JSONP(此解决方式已过时)
- 2. CORS(此方案需要服务器配合)
- 1)CORS概念
- 2)简单请求与复杂请求
- 3)解决简单跨域请求
- 4)解决复杂跨域
- 3. nginx
- 4. 利用前端脚手架
- 5. 自己配置代理服务器(node http-proxy-middleware库)
首先了解什么是跨域
1. 什么是跨域?
跨域是指在一个域的Web页面请求另一个域的资源时,由于浏览器的同源策略限制,这种请求可能会被阻止。
2. 源是什么?
https://www.baidu.com:8099
源 = 协议(https) + 域名(www.baidu.com) + 端口号(8099)
判断是否同源:
3. 同源策略又是什么?
同源策略是浏览器为了确保资源安全所遵循的一种安全策略
4. 同源请求与非同源请求
所处源与目标源不一致即为不同源,也就是跨域请求。
5. 浏览器对跨域请求的限制有哪些?
1)DOM访问限制: 源A的脚本不能访问到源B的DOM(可用ifream验证)
2)Cookie访问限制: 源A不能访问到源B的Cookie
3)Ajax响应数据限制:源A可以向源B发送请求,但是接收不到源B的响应数据
注意点:
- 跨域只发生在浏览器端,服务端不存在跨域限制
- 即使跨域, ajax请求可以发出,但是响应数据不会交给开发者
<link> <script> <img>
等标签请求也可能跨域,但是浏览器对标请求不做严格限制
解决跨域方案
1. JSONP(此解决方式已过时)
- 原理 通过在页面里添加script标签来实现跨域
function requestCall(data){console.log(data);
}let script = document.createElement('script')
script.type = 'text/javascript'
script.src = `https://www.abc.com:8099?callback=requestCall`;
document.body.appendChild(script);script.onload = ()={script.remove();
}
- jquery 封装的JSONP
$.getJSON(`https://www.abc.com:8099?callback=?`, (data)=>{console.log(data);
})
2. CORS(此方案需要服务器配合)
1)CORS概念
2)简单请求与复杂请求
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/2840f275d70e40ae9605a359c5a66d56.png)
关于预检请求:
- 发送时机:发送跨域请求之前有浏览器主动发出
- 主要作用: 用于向服务端确认,是否允许接下来的跨域请求
- 基本流程:先发OPTIONS请求,如果用过预检,则继续发跨域请求
- 请求头内容:
请求头 | 含义 |
---|---|
Origin | 请求源 |
Accsess-Control-Request-Header | 实现请求的请求头 |
Accsess-Control-Request-Method | 请求方法 |
3)解决简单跨域请求
请求头里面一般有```Origin```,表明发送请求的源
服务器给出响应时配置响应头Accsess-Control-Allow-Origin
表明允许跨域,随后浏览器校验时即可通过
4)解决复杂跨域
先让浏览器通过预检配置如下响应头
响应头 | 含义 |
---|---|
Accsess-Control-Allow-Origin | 请求源 |
Accsess-Control-Allow-Header | 允许请求头 |
Accsess-Control-Allow-Method | 允许方法 |
Accsess-Control-Max-Age | 本次预检请求的有效期,单位为秒 |
在处理真正的跨域请求 解决方案同简单跨域请求
可以寻找对应的库解决(node的cors)
3. nginx
location /user/ {proxy_pass url;
}
4. 利用前端脚手架
module.exports = {...
devServer: {proxy: {'/api': {target: 'http://abc.com/login', // 后台接口域名secure: false, // 如果是https接口,需要配置这个参数changeOrigin: true, //是否跨域pathRewrite: {'/api': ''}}}}
5. 自己配置代理服务器(node http-proxy-middleware库)
app.use("/api",createProxyMiddleware({target: 'http://localhost:3001',changeOrigin:true,pathRewrite: {'/api': ''});
学习资源出处