一、跨域出现的原因
1、浏览器限制(同源策略的限制)
同源策略即:同一协议,同一域名,同一端口号。当其中一个不满足时,我们的请求即会发生跨域问题。
2、跨域(例如:localhost:8080/getReq 和 localhost:8081/getReq 虽然同为localhost 但是端口号不一样,同样属于跨域)
3、xmlHttprequest(可扩展超文本传输请求)
在 IE 5 和 IE 6 中,必须使用特定于 IE 的 ActiveXObject() 构造函数
例如:
var XMLHttp=null;
if (window.XMLHttpRequest)
{
XMLHttp=new XMLHttpRequest()
}else if (window.ActiveXObject)
{
XMLHttp=new ActiveXObject("Microsoft.XMLHTTP")
}
解释:
首先创建一个作为 XMLHttpRequest 对象使用的 XMLHttp 变量。把它的值设置为 null。
然后测试 window.XMLHttpRequest 对象是否可用。在新版本的 Firefox, Mozilla, Opera 以及 Safari 浏览器中,该对象是可用的。
如果可用,则用它创建一个新对象:XMLHttp=new XMLHttpRequest()
如果不可用,则检测 window.ActiveXObject 是否可用。在 Internet Explorer version 5.5 及更高的版本中,该对象是可用的。
如果可用,使用它来创建一个新对象:XMLHttp=new ActiveXObject()
二、解决思路
1、通过指定参数让浏览器不做限制(不推荐,需要客户端改动)
2、通过JSONP方式不通过XHR请求(不推荐,有弊端,只能用get请求)
动态创建script,在script中发出一个请求,例如:通过图片的src=" url",发出的请求不会出现跨域,不受同源策略的限制(后续补充)
3、解决跨域
a、被调用方(被调用的后端代码)进行更改,叫支持跨域
b、调用方(前端调用代码)进行更改,叫隐藏跨域
通过代理,从浏览器发出都是A域名的请求,在代理中将指定的url转到B域名里面,浏览器最终会认为是同一个域名,从而解决跨域安全问题。
三、具体解决方法
1、jsonp 解决跨域
<button id="btn">获取信息</button>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$('#btn').click(function(){
var frame = document.createElement('script');
frame.src = 'http://localhost:8080/getReq?name=xxx&age=12&callback=callbackFunction';
$('body').append(frame);
});
function callbackFunction(res){
console.log(res.message+res.name+'你已经'+res.age+'岁了');
}
</script>
点击按钮创建script标签,并发送get请求到src指向的地址 (这里必须使用scipt标签,否则返回的数据不会被当作js执行);
重点在callback参数,这是自定义方法(请求发送出去了,我们只能通过callback来获取接口返回过来的参数)
callback(callbackFunction)这个函数需要服务端接收到请求后调用,所以callback参数定义的方法需要前后端提前约定好。
服务端实现逻辑
router.get('/getReq', (req, res) => {
console.log(req.query, '123'); // req.query 获取前端传过来的参数 例如:req.query.age
let data = {
message: 'success',
name: '这是返回的名称',
age: '这是返回的年龄'
}
data = JSON.stringify(data)
res.end('callbackFunction(' + data + ')');
});