通过实例解析json与jsonp原理及使用方法


Posted in Javascript onSeptember 27, 2020

1.json与jsonp的引入

在ajax中 JSON用来解决数据交换问题,而JSONP来实现跨域。

备注:跨域也可以通过服务器端代理来解决;

理解:JSON是一种数据交换格式,而JSONP是一种依靠开发人员的聪明才智创造出的一种非官方跨域数据交互协议。

2.JSON:是一种基于文本的数据交换方式,或者叫做数据描述格式,是否该选用它首先肯定要关注它所拥有的优点。

JSON的优点:

  • 1) 基于纯文本,跨平台传递极其简单;
  • 2) Javascript原生支持,后台语言几乎全部支持;
  • 3) 轻量级数据格式,占用字符数量极少,特别适合互联网传递;
  • 4) 可读性较强,虽然比不上XML那么一目了然,但在合理的依次缩进之后还是很容易识别的;
  • 5) 容易编写和解析,当然前提是你要知道数据结构;

JSON的格式或者叫规则:

JSON能够以非常简单的方式来描述数据结构,XML能做的它都能做,因此在跨平台方面两者完全不分伯仲。

  • 1) JSON只有两种数据类型描述符,大括号{}和方括号[],其余英文冒号:是映射符,英文逗号,是分隔符,英文双引号""是定义符。
  • 2) 大括号{}用来描述一组“不同类型的无序键值对集合”(每个键值对可以理解为OOP的属性描述),方括号[]用来描述一组“相同类型的有序数据集合”(可对应OOP的数组)。
  • 3) 上述两种集合中若有多个子项,则通过英文逗号,进行分隔。
  • 4) 键值对以英文冒号:进行分隔,并且建议键名都加上英文双引号"",以便于不同语言的解析。
  • 5) JSON内部常用数据类型无非就是字符串、数字、布尔、日期、null 这么几个,字符串必须用双引号引起来,其余的都不用,日期类型比较特殊,这里就不展开讲述了,

只是建议如果客户端没有按日期排序功能需求的话,那么把日期时间直接作为字符串传递就好,可以省去很多麻烦。

示列1:{} 用来描述一组“不同类型的无序键值对集合”
    var person = {
      "Name": "Bob",
      "Age": 32,
      "Company": "IBM",
      "Engineer": true
    }
  示列2:[] 用来描述一组“相同类型的有序数据集合”
    var members = [
      {
        "Name": "Bob",
        "Age": 32,
        "Company": "IBM",
        "Engineer": true
      },
      {
        "Name": "John",
        "Age": 20,
        "Company": "Oracle",
        "Engineer": false
      },
      {
        "Name": "Henry",
        "Age": 45,
        "Company": "Microsoft",
        "Engineer": false
      }
    ]
    //读取其中John的公司名称
    var johnsCompany = members[1].Company;
  
  示列3:{}中包含的[]使用
    var conference = {
      "Conference": "Future Marketing",
      "Date": "2012-6-1",
      "Address": "Beijing",
      "Members":
      [
        {
          "Name": "Bob",
          "Age": 32,
          "Company": "IBM",
          "Engineer": true
        },
        {
          "Name": "John",
          "Age": 20,
          "Company": "Oracle",
          "Engineer": false
        },
        {
          "Name": "Henry",
          "Age": 45,
          "Company": "Microsoft",
          "Engineer": false
        }
      ]
    }
  
    // 读取参会者Henry是否工程师
    var henryIsAnEngineer = conference.Members[2].Engineer;

3.什么是JSONP

JSONP(JSON with Padding)是资料格式 JSON 的一种“使用模式”,可以让网页从别的网域要资料。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的 <script> 元素是一个例外。利用<script> 元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的 JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。

3.1 JSOPN跨域的原理:script标签的src属性,支持跨域;它的基本思想是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

3.2 JSOP包含两部分:回调函数和数据,回调函数是在响应到来时应该调用的函数,一般通过查询字符串添加; 数据就是传入回调函数中的JSON数据,确切的说,是一个JSON对象,可以直接访问。

3.3 JSONP的缺点:

1) 只能实现GET,没有POST;

2) 从其他域中加载的代码可能不安全;难以确定JSONP请求是否失败(XHR有error事件),常见做法是使用定时器指定响应的允许时间,超出时间认为响应失败。

为了方便客户端使用数据逐渐形成非正式传输协议jsonp该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住json数据 这样客户端就可以随意定制自己的函数来自动处理返回数据

示列:

function ajaxFun(){
      var strUrl="http://www.b.com/demo/json.txt";
       $.ajax({
        type:"get",
        url:strUrl,
        dataType: 'jsonp',
        jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
        jsonpCallback: "flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
        success: function(data){
          alert('您查到的信息:票价' + data.price + '元,余-票' + data.tickets + '张。');
        },
        error: function(XMLHttpRequest,textStatus,errorThrown){
          alert("error");
          // 状态码
          console.log(XMLHttpRequest.status);
          // 状态
          console.log(XMLHttpRequest.readyState);
          // 错误信息  
          console.log(textStatus);
         }
      });
    }

备注:

其中 sucess中的代码片段也可以不写,可以单独建立一个回调函数来调用返回的数据。如下一样可以获得数据。

var flightHandler = function (data) {
alert('您查到的信息:票价' + data.price + '元,余票' + data.tickets + '张。');
};

需要注意的是,ajax跨域请求(jsonp)中,服务端返回数据格式必须是:flightHandler({ "price":"120","tickets":"20"});如果直接这样的json格式{ "price":"120","tickets":"20"},将会报parser error的错误.请注意这个函数最后的分号";",必须加上,否则,如果同一个页面有多个ajax请求, 并且在数据没有返回时,再发出其它ajax请求时,有可能出现parsererror出错提示.这种错误很隐敝,在开发时,不容易发现,在并发测试时,就很容易暴露出.

服务端代码示列:

public String jsonReturn(HttpServletResponse response, String callback, Map<String, Object> jsonMap) {
    if (org.apache.commons.lang.StringUtils.isEmpty(callback)) {
      return appAjaxJson(response, getJson(jsonMap));
    }
    return appAjaxJson(response, callback + "(" + getJson(jsonMap) + ")");
  }

  public String appAjaxJson(HttpServletResponse response, String jsonString) {
    return appAjax(response, jsonString, "text/html");
  }

  public String appAjax(HttpServletResponse response, String content, String type) {
    try {
      response.setContentType(type + ";charset=UTF-8");
      response.setHeader("Access-Control-Allow-Origin", "*");//表示支持跨域请求
      // 如果IE浏览器则设置头信息如下
      if ("IE".equals(type)) {
        response.addHeader("XDomainRequestAllowed", "1");
      }
      response.setHeader("Pragma", "No-cache");
      response.setHeader("Cache-Control", "no-cache");
      response.setDateHeader("Expires", 0);
      response.getWriter().write(content);
      response.getWriter().flush();
    } catch (IOException e) {
      this.logException(e);
    }
    return null;
  }

4、JSON.stringify()、JSON.parse()、toString()

4.1 JSON.stringify():将入参(JavaScript值)转换为 JSON 字符串;

示列1:
  let arr = [1,2,3];
  JSON.stringify(arr);//"[1,2,3]"
  typeof JSON.stringify(arr);//"string"

  示例2:
  //判断数组是否包含某对象
  let data = [
    {name:'echo'},
    {name:'听风是风'},
    {name:'天子笑'},
    ],
    val = {name:'天子笑'};
  JSON.stringify(data).indexOf(JSON.stringify(val)) !== -1;//true

  //判断两数组/对象是否相等
  let a = [1,2,3],
    b = [1,2,3];
  JSON.stringify(a) === JSON.stringify(b);//true

4.2 JSON.parse():将JSON字符串转为一个对象;

示列:

let string = '[1,2,3]';
console.log(JSON.parse(string))//[1,2,3]
console.log(typeof JSON.parse(string))//object

4.3 JSON.stringify()与 toString()的区别

let arr = [1,2,3];
JSON.stringify(arr);//'[1,2,3]'
arr.toString();//1,2,3

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript省市联动实现代码
Feb 15 Javascript
javascript实现的元素拖动函数宿主为浏览器
Jul 21 Javascript
使用Jquery实现每日签到功能
Apr 03 Javascript
HTML5实现留言和回复页面样式
Jul 22 Javascript
jQuery基础的工厂函数以及定时器的经典实例分析
May 20 Javascript
JS实现获取图片大小和预览的方法完整实例【兼容IE和其它浏览器】
Apr 24 Javascript
jQuery回调方法使用示例
Jun 26 jQuery
分析javascript中9 个常见错误阻碍你进步
Sep 18 Javascript
vue 文件目录结构详解
Nov 24 Javascript
微信小程序日期时间选择器使用方法
Feb 01 Javascript
axios post提交formdata的实例
Mar 16 Javascript
react 不用插件实现数字滚动的效果示例
Apr 14 Javascript
React 条件渲染最佳实践小结(7种)
Sep 27 #Javascript
VUE 项目在IE11白屏报错 SCRIPT1002: 语法错误的解决
Sep 27 #Javascript
react-intl实现React国际化多语言的方法
Sep 27 #Javascript
Javascript异步流程控制之串行执行详解
Sep 27 #Javascript
vue+elementUI 实现内容区域高度自适应的示例
Sep 26 #Javascript
Openlayers实现测量功能
Sep 25 #Javascript
openlayers4.6.5实现距离量测和面积量测
Sep 25 #Javascript
You might like
全面解析PHP操作Memcache基本函数
2016/07/14 PHP
Laravel5中防止XSS跨站攻击的方法
2016/10/10 PHP
php实现的网页版剪刀石头布游戏示例
2016/11/25 PHP
PHP实现生成推广海报的方法详解
2018/03/14 PHP
ThinkPHP5&amp;5.1实现验证码的生成、使用及点击刷新功能示例
2020/02/07 PHP
js版本A*寻路算法
2006/12/22 Javascript
网站页面自动跳转实现方法PHP、JSP(下)
2010/08/01 Javascript
详解JavaScript中数组的相关知识
2015/07/29 Javascript
jquery获取文档高度和窗口高度汇总
2016/01/25 Javascript
js转html实体的方法
2016/09/27 Javascript
基于vue,vue-router, vuex及addRoutes进行权限控制问题
2018/05/02 Javascript
JavaScript中concat复制数组方法浅析
2019/01/20 Javascript
了解javascript中let和var及const关键字的区别
2019/05/24 Javascript
antd-日历组件,前后禁止选择,只能选中间一部分的实例
2020/10/29 Javascript
JavaScript实现HTML导航栏下拉菜单
2020/11/25 Javascript
vue 计算属性和侦听器的使用小结
2021/01/25 Vue.js
[02:43]2018DOTA2亚洲邀请赛主赛事首日TOP5
2018/04/04 DOTA
python获取糗百图片代码实例
2013/12/18 Python
使用Python的PEAK来适配协议的教程
2015/04/14 Python
Python编程实现输入某年某月某日计算出这一天是该年第几天的方法
2017/04/18 Python
Python入门_浅谈字符串的分片与索引、字符串的方法
2017/05/16 Python
Python对Excel按列值筛选并拆分表格到多个文件的代码
2019/11/05 Python
Django自定义用户表+自定义admin后台中的字段实例
2019/11/18 Python
Python利用FFT进行简单滤波的实现
2020/02/26 Python
python实现单张图像拼接与批量图片拼接
2020/03/23 Python
HTML5 Canvas API中drawImage()方法的使用实例
2016/03/25 HTML / CSS
HTML5 实现图片上传预处理功能
2020/02/06 HTML / CSS
Tripadvisor新西兰:阅读评论,比较价格和酒店预订
2018/02/10 全球购物
Roxy荷兰官方网站:冲浪、滑雪板、服装和配件
2019/10/22 全球购物
大学生饮食配送创业计划书
2014/01/04 职场文书
医药营销个人求职信
2014/04/12 职场文书
英文道歉信
2015/01/20 职场文书
升学宴学生致辞
2015/07/27 职场文书
SQL Server中交叉联接的用法详解
2021/04/22 SQL Server
Html5生成验证码的示例代码
2021/05/10 Javascript
Vue2项目中对百度地图的封装使用详解
2022/06/16 Vue.js