jsonp理解
我们都知道在前端需要考虑跨域的问题,通常这都是后端解决的,在开发环境中我们还可以使用代理,例如在vue脚手架中设置代理。不过在多种解决跨域的方案中有一张方法是使用script标签解决跨域问题,但这只能解决get请求,还需要后端的配合。
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="get">用Jsonp发起get请求</button>
<script>
document.getElementById('get').addEventListener('click', function(){
const script = document.createElement('script');
script.src = "http://127.0.0.1:81/api/jsonP?callBack=test";
document.body.appendChild(script);
});
function test({name}){
console.log(`我爱${name}`);
}
</script>
</body>
</html>
服务端代码
我是用node.js的express框架:大家使用时记得先在终端node install express
const express = require('express');
const app = express();
app.get('/api/jsonP',(req, res) => {
const callback = req.query.callBack;
console.log(callback);
res.send(`${callback}({
name:"小黄",
age:19
})`);
})
app.listen(81,()=>{
console.log('http://127.0.0.1:81')
});
原理很简单,就是script不受到浏览器的同源策略的限制,当我们使用cdn引入外部js文件的时候,比如这样引入jquery的文件,script发送的get请求不会受到同源策略的影响。我们可以通过script标签拿到我们想要的数据,我们可以在前端定义函数,当我们在body中添加script标签,它的src属性是向服务器发起get请求,query参数是在前端的函数名。在服务端,我们可以返回一段字符串,里面存放的是函数的调用和实参,这样我们就以实参的方式拿到了服务器的数据。
结语
这样取解决跨域的问题其实很麻烦,本来后端很容易解决的问题,需要前端定义函数,添加script标签,后端还要配合返回函数的调用,而且每使用一次jsonp就会在页面中增加一个script标签。但是我们可以发现,jsonp是通过在前端定义函数,在我们需要拿到数据的时候,就向服务端通过script发送请求,以达到触发函数,通过实参拿到数据的目的。
我们在学习vue的时候,也会遇到子组件去修改父组件数据的问题或是子组件传递父组件数据的问题。例如,父组件给子组件一组数据,子组件想要修改数据,是不能在子组件内修改的,而是应该让父组件修改,子组件再重新获取,哪怕是父组件传递的是一个引用类型,子组件修改了父组件那也能发生改变,这也是不符合规范的。我们在vue中可以通过自定义事件,事件总线,消息订阅与发布的方式去处理以上的问题,本质上也是想要拿到数据的一方在某个地方绑定事件,传递函数,让有数据的一方去触发,以实参的形式传递数据。这种处理方式和jsonp的方式大同小异。(doge)