前言

  • 这边文档希望通过自己对jsonp的理解,能够采用最简单、最直白的语言告诉大家jsonp是干嘛的!当然,其间难免有纰漏之处,希指正出来!

jsonp能解决的问题

  • 首先我们需要jsonp是干嘛的,它是一种解决浏览器跨域问题的方案,说道这里什么是浏览器跨域呢!说白了,就是浏览器内部有一种机制为了保证每个站点之间的请求达到安全、独立,相互交互不乱套等,浏览器阻止了不同源站点之间的请求。如果不采用跨域的话,浏览器将会报错的。我们先来看个简单例子吧:实例代码1
  1. <!DOCTYPE html>
  2. <html lang="Zh-cn">
  3. <head>
  4. <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1.0"/>
  6. <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"/>
  7. <meta name="renderer" content="webkit"/>
  8. <meta name="Keywords" content=""/>
  9. <meta name="description" content=""/>
  10. <title>demo</title>
  11. </head>
  12. <body>
  13. <script type="text/javascript">
  14. (function(){
  15. var xhr = new XMLHttpRequest();
  16. xhr.open('GET','http://localhost/demo/demo1.php',true);
  17. xhr.send();
  18. xhr.onreadystatechange = function(){
  19. if(xhr.status == 200 && xhr.readyState == 4){
  20. console.log(xhr.responseText);
  21. }else{
  22. console.log('什么都没有');
  23. };
  24. };
  25. xhr.onerror = function(){
  26. console.log('请求出错了!');
  27. };
  28. })();
  29. </script>
  30. </body>
  31. </html>

我们通过上面的页面在请求资源时可以看到下面请求跨域错误提示:

07. 最简单的语言带领大家认识jsonp - 图1

怎样理解跨域,以及它跟浏览器的关系呢!

  • 首先我们不想把概念说的神乎其神,但是大家要理解下面说的话,可以先看下《http报文权威指南》了解下相关概念!这里指出一下,如果只是从http请求的方面来说,上面的页面请求是没有什么问题的,而且也不会报错,因为http本身是无状态的,它也不知道请求的是谁,被请求的是谁,它只知道客户端有请求,服务器把客户端需要的东西返回就好了!上面的页面之所以会报错,是由于浏览器自己带有了一种叫做同源策略的安全机制产生的!

  • 什么是同源策略,相关概念可以自行google或百度,说白了就是一种机制促使浏览器限制不同源之间的请求。这里说一下什么样的请求是不同源的,看下面的表格:

















http://www.demo.com https://www.demo.com 这是不同源的,因为协议不同
http://www.demo1.com http://www.demo2.com 这是不同源的,因为主机不同
http://www.demo.com:80 http://www.demo.com:8080 这是不同源的,因为端口号不同

怎么解决跨域请求问题呢!

  • 常见的和自己熟悉有几种方案,如:1、用cros;2、用代理;3、使用jsonp。这里只对jsonp介绍,其他的方案可以自行查看相关文档。

jsonp的原理

  • jsonp原理其实很简单,首先我们先回归一个现实:我们发现,当我们在html插入img、a、script标签的时候,它们是没有同源限制的。所以jsonp的原理就是利用img、script等标签插入一个请求地址,让不同源的请求远离浏览器的同源策略限制。

实(示)例

  1. <!DOCTYPE html>
  2. <html lang="Zh-cn">
  3. <head>
  4. <meta charset="utf-8"/>
  5. <title>demo</title>
  6. </head>
  7. <body>
  8. <script type="text/javascript" src="http://localhost/demo/demo1.php"></script>
  9. </body>
  10. </html>

后台demo1.php代码如下:

  1. <?php
  2. echo "console.log('欢迎访问demo1.php页面')";
  3. ?>

控制台打印结果截图如下:

07. 最简单的语言带领大家认识jsonp - 图2

怎么实现精确回调呢!

  • 有时候我们并不是只是见到的得到后台数据就好了,还要到前台进行一些处理,那怎么做呢!恩,没错就是使用回调,首先说一下思路:1、首先在页面中定义好回调函数;2、然后在页面通过插入相关标签待query参数的形式实现jsonp请求传递回调函数名字;3、后台得到回调函数名字,并将需要处理的数据传递给回调函数,最后向前台返回回调函数的“调用”,最后一步切记是传回回调函数的调用。示例如下:

前台代码

  1. <!DOCTYPE html>
  2. <html lang="Zh-cn">
  3. <head>
  4. <meta charset="utf-8"/>
  5. <title>demo</title>
  6. </head>
  7. <body>
  8. <script type="text/javascript">
  9. //第一步,现在前台定义回调函数
  10. function addNum(num1,num2){
  11. var sum = num1 + num2;
  12. console.log("两数相加的结果是"+sum);
  13. return sum;
  14. };
  15. //第二步,插入script标签并通过传入query参数的形式传递回调函数的名字给后台
  16. (function(){
  17. var _script = document.createElement('script');
  18. _script.type = 'text/javascript';
  19. _script.src = 'http://localhost/demo/demo2.php?callback=addNum';
  20. document.body.appendChild(_script);
  21. })();
  22. </script>
  23. </body>
  24. </html>

后台demo2.php代码如下:

  1. <?php
  2. /*第三步,获取前台传过来的回调函数的名字*/
  3. $fontEndCallback = $_GET['callback'];//addNum;
  4. /*这里我们先模拟两个数据$num1,$num2,
  5. 实际生产环境中可能就是查询数据库等操作获取数据
  6. */
  7. $num1 = 15;
  8. $num2 = 30;
  9. /*最后切记是返回回调函数的调用,一定记得是调用*/
  10. echo $fontEndCallback."($num1,$num2)";//这里的‘.’相当于js里面的字符串连接操作,等同+
  11. ?>

控制台结果截图如下:

07. 最简单的语言带领大家认识jsonp - 图3

只要弄懂这三步你就会对jsonp心领神会了!

jsonp跟ajax的区别、jsonp和json的区别

  • 首先严格来说,jsonp和ajax是没有关系,唯一的相同点可能就是都是向后台发请求!jsonp和json也是没有关系的,虽然看上去名字很像,但是jsonp描述的是一种请求数据的跨域方式,而json是一种数据格式!

时间仓促,写得不对的地方,后期会持续修改……