解决跨域之—— JSONP

跨域

跨域,被称为面试官100%、10000%会问的问题

解决跨域的方法有很多,这里详细讲下JSONP,其他方法后续可能也会写文章, 首先 JSONPJSON 没有任何关系,就像 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('项目已启动');
}) 

当前端发送请求时,因为不符合浏览器的同源策略,会触发跨域

前端显示

后端显示

可以看出来,后端收到了前端发送的请求,但是前端并没有收到后端的响应。

说明跨域发生在后端响应回来的数据,在前端接收的时候被浏览器的跨域机制拦截了下来

解决跨域的方法之——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('项目已启动');
}) 

前端显示

后端显示

3. JSONP实现原理

前端在window声明一个方法,此时并没有调用

 window[cb] = (data) => {resolve(data)} 

1.因为script请求的数据,浏览器引擎会直接执行,好比请求的 jquery,引擎会执行这段代码
2.因为script请求的数据,我们没有办法直接操作,或者说请求到的数据我们实际上看不见,但是存在

所以在后端以函数形式返回给前端时,并且前端已经声明过这个函数,函数会直接调用,此时data为后端返回数据

4.JSONP缺点: 只支持get类型请求

在考虑到安全性的时候,不适用,因为get请求携带的参数会在url地址显示

结束了!!!

最后

最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值