JSONP原理及应用实例详解


Posted in Javascript onSeptember 13, 2018

JSONP 被用于跨域获取数据。在讲解它之前,先讲讲它与 JSON 之间的区别

什么是JSON?

JSON 是一种基于文本的数据交换方式,或者叫做数据描述格式。

其优点是:

1、基于纯文本,跨平台传递极其简单;

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

3、轻量级数据格式,占用字符数量极少,特别适合互联网传递;

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

5、容易编写和解析,当然前提是你要知道数据结构;

JSON 的缺点当然也有,跨域无法获取数据,而 JSONP 的出现正好弥补了这一缺陷

什么是JSONP?

JSONP 是一种依靠开发人员的聪明才智创造出的一种非官方跨域数据交互协议,其本质就是 js 文件。

JSONP的客户端具体实现

  • Web页面上调用js文件时不受是否跨域的影响(不仅如此,凡是拥有"src"这个属性的标签都拥有跨域的能力,比如<script>、<img>、<iframe>)
  • 跨域js文件中的代码(当然指符合web脚本安全策略的),web页面也是可以无条件执行的。

接下来将以具体实例解释 JSONP 的原理,首先确保你的电脑上安装了nodejs

1.建立本地 web 服务器

新建文件夹 jsonp, 进入该文件夹内打开命令行工具

npm install koa koa-static

新建 index.js 文件

// index.js
const Koa = require('koa')
const app = new Koa()
app.use(require('koa-static')(__dirname + '/public'))
app.listen(3000)

2.新建 public 文件夹后进入文件夹,创建 index.html, somejsonp.js文件

// index.html
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
</head>
<body>
 <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
 <script>
  var localHandler = function(data){
   alert('我是本地函数,可以被跨域的remote.js文件调用,远程js带来的数据是:' + data.result);
  };
 </script>
 <script type="text/javascript" src="./somejsonp.js"></script>
</body>
</html>
// somejsonp.js
localHandler({"result":"我是远程js带来的数据"});

3.然后回到 jsonp 文件夹,输入命令node index.js后,用浏览器打开http://localhost:3000即可看到浏览器窗口弹出js文件中的result,也就是我们获取到了js的数据。这便是jsonp的基本原理。

动态获取 JSONP 的数据,就是在页面中动态插入一段script标签,scr中包含路径及参数,这样后台可根据参数动态生成JS文件,涉及后台实现,这里不做过多阐述。

JSONP 在 JQuery 中的具体实现

jquery 中对于 jsonp 的封装也是基于以上原理,下面是基于 jquery 的代码

修改index.html

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
</head>
<body>
 <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
 <script>
  $.ajax({
    url: 'http://localhost:3000/somejsonp.js',
    dataType: "jsonp",
    jsonp: "callback",
    jsonpCallback: "localHandler",
    success: function (data) {
     alert(data.result)
    }
  }) 
 </script>
</body>
</html>

jquery 动态生成script标签,并定义好方法。前提是jsonpCallback的方法名与引入的js文件方法名一致。

重新刷新页面即可看到弹出框中获取的 jsonp 中的数据。

简单描述就是——先定义一个方法,然后引入外部JS调用这个方法并携带数据。

具体示例

在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。 而JSONP就是通过script节点中的src属性调用跨域的请求。当我们通过JSONP模式请求跨域资源时,服务器返回给客户端一段javascript代码,这段javascript代码自动调用客户端回调函数。

前端

<!DOCTYPE html>
<head>
  <title>jsonp</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<script>
  //动态创建script标签,并请求
  function addScriptTag(src){
    var script = document.createElement('script');
    script.setAttribute('type', 'text/javascript');
    script.src = src;
    document.body.appendChild(script);
  };
  //在onload后,跨域请求
  window.onload = function(){
    addScriptTag('http://127.0.0.1:8080/jsonp?callback=test');
  };
  //回调函数,必须为全局,不然会报错
  function test(data){
    alert(data.name);
  };
</script>
</body>
</html>

搭建node server

//告诉Node.js引入http模块给该服务器应用使用
var http = require('http');
//引入url模块解析url字符串
var url = require('url');
//引入querystring模块处理query字符串
var querystring = require('querystring');
//创建新的HTTP服务器
var server = http.createServer();
//通过request事件来响应request请求
server.on('request',function(req, res){
  var urlPath = url.parse(req.url).pathname;
  var qs = querystring.parse(req.url.split('?')[1]);
  if(urlPath === '/jsonp' && qs.callback){
    res.writeHead(200,{'Content-Type':'application/json;charset=utf-8'});
    var data = {
      "name": "Monkey"
    };
    data = JSON.stringify(data);
    var callback = qs.callback+'('+data+');';
    res.end(callback);
  }
  else{
    res.writeHead(200, {'Content-Type':'text/html;charset=utf-8'});
    res.end('Hell World\n');
  }
});
//监听8080端口
server.listen('8080');
//用于提示我们服务器启动成功
console.log('Server running!');

运行node server之后,在浏览器打开上面所写的html页面,运行结果为:

JSONP原理及应用实例详解

以上就是对于 JSONP 的简洁描述,希望对你有帮助。也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
读jQuery之十一 添加事件核心方法
Jul 31 Javascript
iframe中子父类窗口调用JS的方法及注意事项
Aug 25 Javascript
jQuery实现鼠标经过购物车出现下拉框代码(推荐)
Jul 21 Javascript
Vue-router路由判断页面未登录跳转到登录页面的实例
Oct 26 Javascript
微信小程序通过保存图片分享到朋友圈功能
May 24 Javascript
详解webpack-dev-server使用方法
Sep 14 Javascript
用Object.prototype.toString.call(obj)检测对象类型原因分析
Oct 11 Javascript
JS尾递归的实现方法及代码优化技巧
Jan 19 Javascript
Vue 组件参数校验与非props特性的方法
Feb 12 Javascript
jQuery实现判断滚动条滚动到document底部的方法分析
Aug 27 jQuery
js实现移动端tab切换时下划线滑动效果
Sep 08 Javascript
vue vantUI实现文件(图片、文档、视频、音频)上传(多文件)
Oct 15 Javascript
解决angularJS中input标签的ng-change事件无效问题
Sep 13 #Javascript
javascript将非数值转换为数值
Sep 13 #Javascript
解决angularjs WdatePicker ng-model的问题
Sep 13 #Javascript
webpack实现一个行内样式px转vw的loader示例
Sep 13 #Javascript
vue项目开发中setTimeout等定时器的管理问题
Sep 13 #Javascript
详解react内联样式使用webpack将px转rem
Sep 13 #Javascript
详解webpack 热更新优化
Sep 13 #Javascript
You might like
用PHP实现弹出消息提示框的两种方法
2013/12/17 PHP
php获取域名的google收录示例
2014/03/24 PHP
Laravel 5 框架入门(二)构建 Pages 的管理功能
2015/04/09 PHP
网站被恶意镜像怎么办 php一段代码轻松搞定(全面版)
2018/10/23 PHP
解决PHPstudy Apache无法启动的问题【亲测有效】
2020/10/30 PHP
HTTP头隐藏PHP版本号实现过程解析
2020/12/09 PHP
JavaScript中的其他对象
2008/01/16 Javascript
js过滤HTML标签以及空格的思路及代码
2013/05/24 Javascript
JS小功能(操作Table--动态添加删除表格及数据)实现代码
2013/11/28 Javascript
jQuery中dom元素上绑定的事件详解
2015/04/24 Javascript
AngularJS Module方法详解
2015/12/08 Javascript
node.js缺少mysql模块运行报错的解决方法
2016/11/13 Javascript
JS实现复制功能
2017/03/01 Javascript
jQuery除指定区域外点击任何地方隐藏DIV功能
2017/11/13 jQuery
详解微信小程序canvas圆角矩形的绘制的方法
2018/08/22 Javascript
nodejs实现获取本地文件夹下图片信息功能示例
2019/06/22 NodeJs
JavaScript创建表格的方法
2020/04/13 Javascript
[52:52]完美世界DOTA2联赛PWL S3 LBZS vs access 第一场 12.10
2020/12/13 DOTA
python 基础教程之Map使用方法
2017/01/17 Python
Python基于递归算法实现的汉诺塔与Fibonacci数列示例
2018/04/18 Python
pytorch 数据集图片显示方法
2018/07/26 Python
在Pycharm中自动添加时间日期作者等信息的方法
2019/01/16 Python
python中logging模块的一些简单用法的使用
2019/02/22 Python
python next()和iter()函数原理解析
2020/02/07 Python
Django 解决阿里云部署同步数据库报错的问题
2020/05/14 Python
css3动画过渡实现鼠标跟随导航效果
2018/02/08 HTML / CSS
美国男士和女士奢侈品折扣手表购物网站:Certified Watch Store
2018/06/13 全球购物
Linux操作面试题
2015/02/11 面试题
小班秋游活动方案
2014/02/22 职场文书
2014年实习班主任工作总结
2014/11/08 职场文书
教师业务学习材料
2014/12/16 职场文书
青年文明号汇报材料
2014/12/23 职场文书
荆州古城导游词
2015/02/06 职场文书
商业计划书如何写?关键问题有哪些?
2019/07/11 职场文书
基于Golang 高并发问题的解决方案
2021/05/08 Golang
十大最强水系宝可梦,最美宝可梦排第三,榜首大家最熟悉
2022/03/18 日漫