简单了解jsonp原理

jsonp是什么

jsonp和json

json是一种轻量级的数据传输格式,一般被用于web应用中,大部分前后端分离的应用都以json格式进行数据传输。
jsonp主要用来解决跨域访问的问题,是一种常见的网络请求方式。
因为ajax直接请求普通文件会存在跨域无权限访问的问题,但是web页面中可以调用js文件,所以解决跨域问题的核心在于通过<script>标签的src来帮助我们请求数据,将请求到的数据当做一个JavaScript的函数来执行,并且在执行的过程中传入我们需要的json,所以封装jsonp的核心在于我们监听window上的jsonp进行回调时的名称。

如何使用jsonp

1.web页面可以无条件执行跨域js文件中的代码(符合web脚本安全策略的)
假设远程服务器remoteserver.com的根目录下有个remote.js代码如下:

  alert('我是远程文件返回数据');

在本地服务器中有个local.html文件页面代码如下:


<head>
    <title></title>
    <script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>

页面执行时将会弹出一个窗体,显示跨域成功。
2.现在在local.html页面定义一个函数,然后在remote.js中传入数据进行调用
本地local.js页面代码如下所示:

<head>
    <title></title>
    <script type="text/javascript">
    var localHandler = function(data){
        alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result);
    };
    </script>
    <script type="text/javascript" src="http://remoteserver.com/remote.js"></script>
</head>

远程remote.js的文件代码如下:

localHandler({"result":"我是远程js的数据"});

运行之后就可以查看到本地的函数被跨域的远程js调用,并且还可以接收到远程js的数据,接下来我们就要解决远程js如何知道它应该调用哪个本地函数。
3.所以服务端提供的脚本需要是动态生成的,调用者可以传一个参数过去告诉服务端需要调用哪段函数并返回,这样服务器就可以按照客户端的需求来生成js脚本并响应
接下来给个例子,如local.html页面的代码:

<head>
    <title></title>
    <script type="text/javascript">
    // 得到航班信息查询结果后的回调函数
    var flightHandler = function(data){
        alert('你查询的航班结果是:票价 ' + data.price + ' 元,' + '余票 ' + data.tickets + ' 张。');
    };
    // 提供jsonp服务的url地址(不管是什么类型的地址,最终生成的返回值都是一段javascript代码)
    var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
    // 创建script标签,设置其属性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script标签加入head,此时调用开始
    document.getElementsByTagName('head')[0].appendChild(script); 
    </script>
</head>

这段代码在调用的url中传递一个code参数,告诉服务器需要查的航班为CA1998,而callback函数则告诉服务器,我的本地回调函数为flightHandler,所以可以把查询结果传入这个函数中进行调用。
4.接下来就是如何把代码进行封装,用于与用户界面进行交互,从而实现多次重复调用

<script>
    let count = 1
    export default function originJSONP(option) {
        // 从传入的option中提取url
        const url = option.url
        // 在body中添加script标签
        const body = document.getElementsByTagName('body')[0]
        const script = document.createElement('script');
        // 在内部产生一个不重复的callback
        const callback = 'jsonp' + count++
        // 监听window上的jsonp调用
        return new Promise((resolve, reject) => {
            try {
                window[callback] = function (result) {
                    body.removeChild(script);
                    resolve(result)
                }
                const params = handleParam(option.data);
                script.src = url + '?callback'+callback
                body.appendChild(script)
            } catch (e) {
                body.removeChild(script)
                reject(e)
            }
        })
    }

    function handleParam(data) {
        let url = ''
        for (let key in data) {
            let value = data[key] !== undefined ? data[key] : ''
            url += `&${key}=${encodeURIComponent(value)}`
        }
        return url
    }
</script>

关于ajax和jsonp的异同:
1.ajax和jsonp在调用方式上相似,都是请求一个url,然后把服务器返回的数据进行处理
2.但ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加script标签调用服务器提供的js脚本
ajax的底层是用XmlHttprequest类来实现异步请求(不刷新页面就可以获得响应数据),所以不能跨域。
他们的区别也不在于是否可以跨域,ajax通过服务端代理也可以跨域,jsonp也可以进行同域的数据获取。

文章参考于https://blog.csdn.net/HansExploration/article/details/80314948

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值