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中的$.getJSON 使用说明
Mar 10 Javascript
js离开或刷新页面检测(且兼容FF,IE,Chrome)
Mar 05 Javascript
基于JavaScript实现弹出框效果
Feb 19 Javascript
新入门node.js必须要知道的概念(必看篇)
Aug 10 Javascript
关于vue中 $emit的用法详解
Apr 12 Javascript
bootstrap-table实现表头固定以及列固定的方法示例
Mar 07 Javascript
详解vue中移动端自适应方案
May 05 Javascript
使用layui监听器监听select下拉框,事件绑定不成功的解决方法
Sep 28 Javascript
浅谈vue中组件绑定事件时是否加.native
Nov 09 Javascript
npx create-react-app xxx创建项目报错的解决办法
Feb 17 Javascript
Node.js API详解之 tty功能与用法实例分析
Apr 27 Javascript
解决Vue-Router升级导致的Uncaught (in promise)问题
Aug 07 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
ThinkPHP访问不存在的模块跳转到404页面的方法
2014/06/19 PHP
PHP未登录自动跳转到登录页面
2016/12/21 PHP
作为PHP程序员你要知道的另外一种日志
2018/07/30 PHP
PHP const定义常量及global定义全局常量实例解析
2020/05/28 PHP
js实现的网站首页随机公告随机公告
2007/03/14 Javascript
Javascript面向对象之四 继承
2011/02/08 Javascript
30个精美的jQuery幻灯片效果插件和教程
2011/08/23 Javascript
JavaScript使用encodeURI()和decodeURI()获取字符串值的方法
2015/08/04 Javascript
基于jQuery Bar Indicator 插件实现进度条展示效果
2015/09/30 Javascript
JavaScript根据CSS的Media Queries来判断浏览设备的方法
2016/05/10 Javascript
Vue.js展示AJAX数据简单示例讲解
2017/03/29 Javascript
JavaScript ES6常用基础知识总结
2019/02/09 Javascript
vue相同路由跳转强制刷新该路由组件操作
2020/08/05 Javascript
[29:10]Ti4 冒泡赛第二天 NEWBEE vs Titan 3
2014/07/15 DOTA
[40:03]DOTA2上海特级锦标赛主赛事日 - 1 败者组第一轮#1EHOME VS Archon
2016/03/02 DOTA
[05:20]2018DOTA2亚洲邀请赛主赛事第三日战况回顾 LGD率先挺进胜者组决赛
2018/04/06 DOTA
利用Python脚本生成sitemap.xml的实现方法
2017/01/31 Python
Python使用win32com实现的模拟浏览器功能示例
2017/07/13 Python
python 对txt中每行内容进行批量替换的方法
2018/07/11 Python
为什么Python中没有&quot;a++&quot;这种写法
2018/11/27 Python
python time.sleep()是睡眠线程还是进程
2019/07/09 Python
python数据归一化及三种方法详解
2019/08/06 Python
python实现画出e指数函数的图像
2019/11/21 Python
CSS3属性box-shadow使用详细教程
2012/01/21 HTML / CSS
英国最大的汽车交易网站:Auto Trader UK
2016/09/23 全球购物
高中考试作弊检讨书
2014/01/14 职场文书
开业庆典策划方案
2014/02/18 职场文书
优秀护士获奖感言
2014/02/20 职场文书
教师求职自荐信
2014/03/09 职场文书
中班幼儿评语大全
2014/04/30 职场文书
社区义诊活动总结
2014/04/30 职场文书
英文求职信范文
2014/05/23 职场文书
搞笑结婚保证书
2015/05/08 职场文书
宣传稿格式范文
2015/07/23 职场文书
2016年6月份红领巾广播稿
2015/12/21 职场文书
SpringBoot中获取profile的方法详解
2022/04/08 Java/Android