跨域
跨域,被称为面试官100%、10000%会问的问题
解决跨域的方法有很多,这里详细讲下JSONP,其他方法后续可能也会写文章, 首先 JSONP和 JSON 没有任何关系,就像 Java 与 JavaScript,林允与林允儿
希望大家看完这篇文章,能了解的知识:
1.出现跨域的原因
2.什么时候会出现跨域
3.JSONP是如何解决跨域的,有什么缺点
出现跨域的原因:浏览器的同源策略
要了解浏览器的同源策略,我们必须知道一段URL地址的组成
例如: https:// www.baidu.com :8080 /userInfo
其中 https是协议号 —— www.baidu.com 是域名—— :8080是端口 ——/userInfo是路径
当协议号和域名和端口都相同时,才符合同源策略
跨域通常发生在什么时候
是在前端发送请求的时候发生跨域,还是在后端接收到请求,响应请求的时候发生跨域?
我们写段简单代码测试一下
前端代码
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
html<button id="btn">获取数据</button>
jslet btn = document.querySelector("#btn");btn.addEventListener("click", function(){$.ajax({url:'http://localhost:3000',data:{name:'yangjun'},method:'GET',success(res){console.log(res);}})},false)
后端代码
const Koa = require('koa')
const app = new Koa()
const main = (ctx,next)=>{console.log(ctx.query);ctx.body = 'hello world'
}
app.use(main)
app.listen(3000,()=>{console.log('项目已启动');
})
当前端发送请求时,因为不符合浏览器的同源策略,会触发跨域
前端显示
![](https://i-blog.csdnimg.cn/blog_migrate/b1acaac8003a1fa0ba109b700b744cd0.png)
后端显示
![](https://i-blog.csdnimg.cn/blog_migrate/b69dc5d766c18391666d9ad2ab0ce053.png)
可以看出来,后端收到了前端发送的请求,但是前端并没有收到后端的响应。
说明跨域发生在后端响应回来的数据,在前端接收的时候被浏览器的跨域机制拦截了下来
解决跨域的方法之——JSONP
1. JSONP思想
JSONP 是一种思想,并不是一个方法, 有些请求是不会受到浏览器的同源策略的影响的。
例如:src、href
1.<script src=""></script>
2.<img src="">
3.<link rel="stylesheet" href="">
JSONP就是利用script 的 src属性加载资源时不受同源策略的影响的这一特性,并且script会将引用的外部文件的文本内容当做js代码来进行解析
2. JSONP实现
前端代码
html<button id="btn">获取数据</button>
jsconst jsonp = (url, params, cb) => {return new Promise((resolve, reject) => {const script = document.createElement('script');params = { ...params, cb: cb }const arr = Object.keys(params).map(key => `${key}=${params[key]}`)script.src = `${url}?${arr.join('&')}`document.body.appendChild(script)//后端会返回一个字符串给前端,cb('我今年18岁')//全局声明一个方法,方法名为cbwindow[cb] = (data) => {resolve(data)}})}let btn = document.getElementById('btn')btn.addEventListener('click', () => {jsonp('http://localhost:3000', { name: '蜗牛', age: 18 }, 'callback').then(res => {console.log(res)})})
后端代码
const Koa = require('koa')
const app = new Koa()
const main = (ctx,next)=>{//console.log(ctx.query); { name: '我', age: '18', cb: 'callback' }const {name,age,cb} = ctx.queryconst userInfo = `${name}今年${age}岁`const str = `${cb}(${JSON.stringify(userInfo)})` // 'callback(userInfo)'//console.log(str); callback("我今年18岁")ctx.body = str
}
app.use(main)
app.listen(3000,()=>{console.log('项目已启动');
})
前端显示
![](https://i-blog.csdnimg.cn/blog_migrate/96acd12bcc5f3b7bbbc40d9eecc8e651.png)
后端显示
![](https://i-blog.csdnimg.cn/blog_migrate/f348dd8266ef93b00fad077108e33560.png)
3. JSONP实现原理
前端在window声明一个方法,此时并没有调用
window[cb] = (data) => {resolve(data)}
1.因为script请求的数据,浏览器引擎会直接执行,好比请求的 jquery,引擎会执行这段代码
2.因为script请求的数据,我们没有办法直接操作,或者说请求到的数据我们实际上看不见,但是存在
所以在后端以函数形式返回给前端时,并且前端已经声明过这个函数,函数会直接调用,此时data为后端返回数据
![](https://i-blog.csdnimg.cn/blog_migrate/27869a62c853dda41540bce62321a32b.png)
4.JSONP缺点: 只支持get类型请求
在考虑到安全性的时候,不适用,因为get请求携带的参数会在url地址显示
结束了!!!
最后
最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。
有需要的小伙伴,可以点击下方卡片领取,无偿分享