说起Ajax,不可避免面临两个问题:
第一个是Ajax以何种格式来交换数据?
第二个是跨域的需求如何解决?首选方案:JSON来传数据,靠JSONP来跨域
jsonp : JSON with Padding
用json去填充,填充什么?填充函数。返回的是一个函数调用!
jsonp原理剖析
- 本质是利用了标签具有可跨域的特性
- 由服务端返回一个预先定义好的JavaScript函数调用
- 将服务器数据以该函数参数的形式传递过来
- 此方法需要前后端配合完成
标签的可跨域性
哪些标签具有可跨域性,可跨域性指的是可以访问到其他网站的资源
iframe、script、video、radio、link
总结下来,其实就是src和href
<link rel="stylesheet" href="http://www.jd.com/css/base.css"/>
</head>
<body>
<img src="http://www.jd.com/images/l2.jpg" alt=""/>
<script src="http://www.jd.com/js/common.js"></script>
</body>
小总结:
- script标签引用的资源会被当成JS去解析和运行
- script标签可以调用跨域的接口地址(即第三方接口)
- 第三方的接口,返回的内容必须符合js语法,否则报错
- 前端和后端配合定义一个相同的方法,这个方法叫回调函数。
- 由于前后端维护困难,会调函数的名字统一由前端定义,传递给后台的参数名字,一般定义为callback。
- 在服务端输出回调函数的时候可以传参,传json格式的数据。
- 数据通过get传递给服务器,通过给回调函数传参,返回数据
1. script标签引用的资源会被当成JS去解析和运行
同源情况下:script标签和link标签还是有很大区别的
一般来说,php只是个程序,执行完之后会解析成字符串。
php里面的Content-Type属性决定按理哪种编码解析
script标签引用的资源会被当成JS去解析和运行,不管Content-Type是什么
<script src="02%20jsonp.php"></script>
link会根据Content-Type是什么来解析成对应的页面
<link rel="stylesheet" href="02%20jsonp.php"/>
<?php
header('Content-Type:text/css;charset=utf-8');
echo '.jsonp{color:red}';
?>
2. script标签可以调用跨域的接口地址(即第三方接口)
跨域情况下:
<script src="http://api.study.com/02%20jsonp.php?"></script>
4. 前端和后端配合定义一个相同的方法,这个方法叫回调函数
后端php:
<?php
header('Content-Type:text/css;charset=utf-8');
/* 1. 定义变量。这种方法可以传数据,但是不好*/
echo 'var data = {name:"luyu"}';
/* 2.调用方法,需要在前端声明*/
echo 'test();';
/* 3.不管前端叫什么名字,都能取到
$callback = $_GET["callback"];
echo $callback.'();';
?>
前端html:
<script>
var test = function(){
console.log("被服务器调用了..");
}
</script>
<script src="http://api.study.com/02%20jsonp.php?"></script>
test()属于回调函数。等script的src资源请求成功之后,才调用test,所以称之为回调函数
5. 由于前后端维护困难,会调函数的名字统一由前端定义。传递给后台的参数名字,一般定义为callback。
后端php:
<?php
header('Content-Type:text/css;charset=utf-8');
/* 3.不管前端叫什么名字,都能取到*/
$callback = $_GET['callback'];
echo $callback.'();';
?>
前端html:
<script>
var test = function(){
console.log("被服务器调用了..");
}
</script>
<--多接口调用的话,改参数对应值即可-->
<script src="http://api.study.com/02%20jsonp.php?callback=test"></script>
6. 这个callback回调函数怎么传递数据?(联想封装ajax)在服务端输出回调函数的时候可以传参,传json格式的数据。
后端php:
<?php
header('Content-Type:text/css;charset=utf-8');
/* 3.不管前端叫什么名字,都能取到*/
$callback = $_GET['callback'];
/* 传参可以传对象,json格式的字符串...
既然可以直接传对象,还有必要传json字符串吗?没必要了..不然回到前端还是得JSON.parse()转成json对象 */
echo $callback.'("success");';
?>
前端html:
<script>
var success = function(data){
console.log(data);
}
</script>
<--多接口调用的话,改参数对应值即可-->
<script src="http://api.study.com/02%20jsonp.php?callback=success"></script>
JSONP和Ajax的异同
ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理。因此jquery等框架都把jsonp作为ajax的一种形式进行封装。
但是,ajsx和jsonp其实本质上是不同的东西。
Ajax的核心是通过XMLHttpRequest 获取非本页内容,而jsonp的核心则是动态添加script标签来调用服务器提供的js脚本。
所以说,ajax和jsonp的区别不在于是否跨域,ajax通过服务器代理一样可以实现跨域,jsonp本身也不排斥同源数据的获取。