最近在做一个云音乐播放器的项目,需要用到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的核心则是动态添加(远程获取的)