详析JSONP跨域

关于跨域这个问题也是大家工作中经常遇到的问题,之前给大家讲解了跨域的基本知识以及如何使用iframe跨域,如果想具体了解iframe跨域可以点击:深入剖析iframe跨域问题。本文主要讲解JSONP的原理,以及JSONP的实际应用。

JSONP的详析流程:

1 什么是JSONP

2 JSONP的原理与实现流程

2.1 JSONP跨域流程

2.2 相关提示

3 JSONP的实例 - 辅助理解JSONP流程

3.1 JSONP跨域实例 - 前端的JS代码

3.2 JSONP跨域实例 - 后台的PHP代码

3.3 代码的注意事项

4 利用JSONP实现百度搜索的关键词获取

4.1 功能需求与效果

4.2 提供的接口(API)说明

4.3 接口返回示例

4.4 实例开发

5 JSONP跨域的优劣势

5.1 JSONP跨域的优点

5.2 JSONP跨域的缺点

5.3 注意事项

1 什么是JSONP

JSONP,是解决跨域的一种解决方案,在这种解决方式当中通过JavaScript类型的数据(多数为对象)进行传递,和JSON的格式很相似,因此我们把这种解决跨域的方案命名为JSONP。

JSONP,可以拆成JSON和P。其中,JSON是一种轻量级的数据格式,可以理解为前端与后台之间协定的一种数据交互格式;换言之,前端识别一些语言,后台识别一些语言,JSON,既能够被前端识别,又能够被后台识别。P表示package(打包、包装)的意思,那么JSONP可以简单的理解为“包装”JSON。

2 JSONP的原理与实现流程

JSONP跨域流程

一图胜千言(为了让大家尽可能看清楚,我们调整成了“纵向”图),如果您想要下载“高清版”,可以发送“”到我们的公众号。

如下流程即为上图流程的“描述”。我们再回顾一下吧~

1 前端通过JS,动态创建一个script标签

2 前端利用script的src,实现不同域后台文件的申请(简言之就是将src的属性值设置为B域中的XX.php等路径)

3、4 前端将需要给后台传递的数据放置在URL串中,还需要将“申请到数据后”想要运行的功能函数“作为参数”传递给后台

5 后台接收到前端传递的数据

6 后台语言根据需求,从数据库中获取数据

7 后台将从数据库中得到的数据以JSON格式存储

8 后台将JSON格式的数据作为“参数”放置在函数中(形成一段JS代码,JS代码的功能就是运行“前端此前定义的功能函数”)

9 后台将JS代码返回前端并运行JS函数

10 在前端中定义的函数被运行,后台传递的数据存在于参数当中(此时我们可以再书写要执行的DOM操作等功能)

相关提示

您在查看JSONP的流程时,可能会产生如下问题:

1 后台需要的参数名,可以随便定义吗?

答案是:不可以,后台是需要根据字段在数据库中进行数据查找的,因此此处不能随便定义。而在开发当中,后台会为前端提供API接口文档,前端只需要查看文档,就能够了解需要使用什么参数名。

2 为何要动态设置JavaScript?

答案是:可以静态设置src,但是这也就意味着参数值会被定死。通常我们都是需要向后退申请某些数据,这些数据有可能是需要用户来定义的,此时,用动态的方式进行创建,可以满足“参数值不确定”的功能需求。

3 JSONP的实例 - 辅助理解JSONP流程

看完理论层面的流程之后,我们再借助一个简单的实例来理解一下。注意:HTML5学堂小编将第一步到第十步的功能分别对应其命令,标注在了注释当中。(对于第四步,本身属于便于理解的层面,并没有对应代码)

该JSONP实例的功能需求:希望在A域中访问http://localhost/h5course中的h5course.php文件,并且获取这个文件返回的内容。A域与http://localhost/h5course处于不同域。

JSONP跨域实例 - 前端的JS代码

// 对应于第一步
var newScript = document.createElement('script');
// 对应于第二步和第三步,第三步为?后面的内容“name=HTML5&callback=callFn”
newScript.src = 'http://localhost/h5course/h5course.php?name=HTML5&callback=callFn';
// 对应于第一步
document.body.appendChild(newScript);
// 对应于第十步
function callFn(data) {
    console.log(data);
}

JSONP跨域实例 - 后台的PHP代码

<?php
    // 对应于第五步
    $id = $_GET['name'];
    $callback = $_GET['callback'];
    // 对应于第六七步,在此定义一个变量,用于存储JSON数据。为$json赋值的数据,为第六步(当前的第六步为模拟实现,真实的第六步需要申请后台数据库)
    $json = '';
    if ($id == 'HTML5') {
        $json = '{
            "name": "HTML5学堂:http://www.h5course.com/"
        }';
    } else {
        $json = '{
            "name": "iOS"
        }';
    }
    // 第八步 将JSON格式的数据作为“参数”放置在函数中
    if ($callback) {
    $result = $callback . '(' . $json . ')';
    }
    // 第九步 将数据传送回去
    echo $result;
?>

运行结果:{name: "HTML5学堂:http://www.h5course.com/"}

代码的注意事项

1 在http://localhost/h5course/h5course.php?name=HTML5&callback=callFn;请求路径中,name是浏览器客户端给服务端发送的一个参数,根据这个参数返回相应的JSON数据;callback是给服务端发送回调函数的名字;

2 服务端代码:实例当中服务端的代码使用的是PHP语言。正常来说服务端(PHP)的代码不需要前端工程师来书写,后台人员会给前端工程师提供请求接口以及接口文档,HTML5学堂小编只是为了让大家理解服务端是如何配合JSONP完成跨域,所以加上了服务端的代码实例。

2.1 $_GET['name'];和$_GET['callback'];获取浏览器客户端传过来的参数,接收到的值分别是HTML5学堂和callFn

2.2 $callback . '(' . $result . ')'; 等价于callFn({"name": "iOS"});或callFn({"name": "HTML5学堂:http://www.h5course.com/"});

3 请保证在服务器环境下运行(自己电脑可以使用wamp,启动服务器)

4 利用JSONP实现百度搜索的关键词获取

功能需求与效果

百度,相信大家都使用过,当我们在百度当中输入一个汉字/字母时,在搜索框部分会出现以这个汉字/字母开头的相关词语。百度这个功能让我们的搜索变得更快捷。而在百度的数据库中存储着这些词的基本数据。我们这次,就通过JSONP跨域,去申请百度的这个PHP文件,实现“相关搜索关键词”(如下图)的功能。

提供的接口(API)说明

接口名称:获取相关关键词

URL:https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su

支持格式:JSON

HTTP请求方式:GET/POST

请求参数:

wd | 必选 | 字符串类型 | 根据指定的wd,返回其对应的相关词
cb | 必选 | 字符串类型 | 指定浏览器客户端的回调函数名
接口返回示例

实例开发

<!doctype  html>
<html>
<head>
  <meta  charset="UTF-8">
  <title>H5course-HTML5学堂  |  刘国利、陈能堡</title>
  <link  rel="stylesheet"  href="css/reset.css">
</head>
<body>
  <div  class="wrap"></div>
  <script>
    //  动态创建script标签
    var  newScript  =  document.createElement("script");


    //  请求是URL路径赋值给script标签的src属性
    newScript.src  =  "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=HTML5学堂&cb=show";
    //  将script标签添加到页面当中
    document.body.appendChild(newScript);


    //  回调函数
    function  show(data)  {
      //  根据接口返回示例,来获取服务器端返回的数据
      var  len  =  data.s.length;


      for  (var  i  =  0;  i  <  len;  i++)  {
        console.log(data.s[i]);        
      };
    }
  </script>
</body>
</html>

5 JSO优劣势

JSONP跨域的优点

1 JSONP能够比较简单的实现跨域功能,并且在请求完毕后可以通过调用[回调]函数的方式获取服务端的数据;

2 JSONP的兼容性非常好,在低端的浏览器中都可以正常运行,不需要XMLHttpRequest或ActiveX的支持;

JSONP跨域的缺点

1 JSONP只支持GET请求而不支持POST等其它类型的HTTP请求;

2 JSONP需要服务器端的配合,无法独立完成跨域。

注意事项

JSONP既能够解决子域的跨域问题,也能够解决不同域的跨域问题。但是不能够在A域中使用JSONP的方式访问B域中的JS文件(请不要陷入这个误区)

HTML5学堂 小编-利利&堡堡 耗时10h

原文发布于微信公众号 - HTML5学堂(h5course-com)

原文发表时间:2016-05-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏企鹅号快讯

ajax 跨域,这应该是最全的解决方案了

问题:我怎么才能收到你们公众号平台的推送文章呢? 前言 从刚接触前端开发起, 这个词就一直以很高的频率在身边重复出现,一直到现在,已经调试过N个跨域相关的问题了...

1925
来自专栏HTML5学堂

postMessage与postMessage跨域

HTML5学堂今日postMessage跨域教学流程 先为大家讲解postMessage的基本知识 之后,我们书写一个实例:使用静态的iframe,实现A域前端...

3626
来自专栏hbbliyong

web跨域解决方案

阅读目录 什么是跨域 常用的几种跨域处理方法: 跨域的原理解析及实现方法 总结 摘要:跨域问题,无论是面试还是平时的工作中,都会遇到,本文总结处理跨域问题的几种...

75610
来自专栏农夫安全

【笔记】记录Cy牛的任意密码重置姿势

跟第三个有点类似,只判断了接收端和验证码是否一致,未判断接收端是否和用户匹配,因此修改接收端可达到重置目的

1112
来自专栏程序员的碎碎念

php实现登录短信验证

今天benny要跟大家说这个其实很简单,就是借用某一个平台的短信api接口实现短信验证,说简单呢,那是因为他的官网:http://www.ucpaas....

4709
来自专栏崔庆才的专栏

轻松获得海量稳定代理!ADSL拨号代理的搭建

8333
来自专栏前端小栈

你真的会使用XMLHttpRequest吗?

我们通常将Ajax等同于XMLHttpRequest,但细究起来它们两个是属于不同维度的2个概念。

993
来自专栏宋凯伦的技术小栈

【工作中学习】CreateProcessAsUser失败,错误码:1314

  事情起因是这样,   产品的Windows服务(Service)之前一直是用Local System Account在运行的,但这个版本有需求要换成使用普通...

2676
来自专栏王二麻子IT技术交流园地

五、VueJs 填坑日记之将接口用webpack代理到本地

上一篇博文,我们已经顺利的从cnodejs.org请求到了数据,但是大家可以注意到我们的/src/api/index.js的第一句就是: // 配置API接口地...

24810
来自专栏Micro_awake web

同源策略和跨域解决方法

第一部分:同源策略:same-origin policy 1.同源策略的由来: 1995年,同源策略由Netscape(曾经的浏览器霸主,拒绝微软收购请求,被I...

2337

扫码关注云+社区