基于JSONP的跨域请求实现

最近在做一个云音乐播放器的项目,需要用到Ajax跨域请求,多次尝试,选择使用JQuery jsonp来实现这个请求。


先简单介绍一些json:

1、基于纯文本,支持跨平台;

2、Javascript原生支持,后台语言几乎全部支持;

3、轻量级数据格式,适合互联网传递;

4、可读性较强,虽然比不上XML那么一目了然,但在合理的依次缩进之后还是很容易识别的;

下面讲一下我对于跨域的理解:

什么是跨域?
跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。

所谓同源是指,域名,协议,端口均相同:

http://www.123.com/index.html 调用 http://www.123.com/server.php (非跨域)

http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)

http://abc.123.com/index.html 调用 http://def.123.com/server.php (子域名不同:abc/def,跨域)

http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php (端口不同:8080/8081,跨域)

http://www.123.com/index.html 调用 https://www.123.com/server.php (协议不同:http/https,跨域)

请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。

补充一点:可以调用不同服务器的js脚本,这样不会产生跨域问题

Jsonp实现思路

假设在A服务器(host_a)上有脚本a.js

alert("invoke a.js")

在服务器B上有页面b.html

<head>
    <title></title>
    <script type="text/javascript" src="http://host_a/a.js"></script>
</head>
<body>

</body>
</html>

毫无疑问会调用成功,弹出提示框”invoke a.js”。

注意:远程服务器上的js文本也能调用本页面中包含的function

所以若将B服务器中的页面B.html中增加一个function:

<head>
    <title></title>
    <script type="text/javascript" src="http://host_a/a.js">
var localHandler = function(data){
        alert('我是本地函数,可以被跨域的a.js文件调用,并且远程函数还能传参数,传的参数为'+data);
    };
</script>
</head>
<body>

</body>
</html>

此时将远程A服务器中的js稍做修改,增加如下代码:

localHandler("远程服务器想要返回的数据");

即可调用本地的localHandler方法并且传回参数

此时跨域远程获取数据的目的基本实现了,但是还存在一个问题:
远程js怎么知道它应该调用的本地函数叫什么名字呢?

此时可以通过GET请求URL的方式,在后面的参数列表中附带回调函数的名字。并且远程服务器在收到GET请求后会根据GET请求附带的信息动态构造一个js脚本(可以通过简单的字符串拼接来完成),
同时本地会动态创建一个script标签,将src属性其指向上述GET请求的URL(这个URL实际上是一段js代码)
本地页面再执行这个脚本,间接地将数据传入回调函数,完成相关操作
本地页面代码如下:

// 回调函数
    var callbackHandler = function(data){
        alert('回掉函数被执行,得到参数'+data);
    };
    // 提供jsonp服务的url地址(动态创建js的地址,用于绑定src属性)
    var url = "http://remote_server/jsonp/a.action?callback=flightHandler";
    // 创建script标签,设置其src属性为上面的url(即为被动态创建的js脚本)
    var script = document.createElement('script');
    script.setAttribute('src', url);
    将得到的js脚本添加到document并运行
    document.getElementsByTagName('head')[0].appendChild(script); 

远程服务器所需要实现的功能只是一些字符串拼接和一些业务逻辑


另外,JQuery有对jsonp的封装,示例代码如下:

 $.ajax({
             type: "get",
             async: false,
             url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
             dataType: "jsonp",
             jsonp: "callback",//传递给请求处理页面,用以获得jsonp回调函数名的参数名(一般默认为:callback)
             jsonpCallback:"namedHandler",//此处可以自定义的jsonp回调函数名称,不写也会有默认值
  //上述两个函数由JQuery自动帮我们创建,我们只需要关心下面的业务处理函数
             success: function(json){
                 alert('得到数据:'+json);
             },
             error: function(){
                 alert('fail');
             }
         });

请注意但ajax和jsonp最大的不同点:
ajax的核心是通过XmlHttpRequest获取非本页内容,获取到的是任意文件
而jsonp的核心则是动态添加(远程获取的)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值