通过实例解析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 相关文章推荐
js验证表单第二部分
Nov 25 Javascript
学习ExtJS border布局
Oct 08 Javascript
javascript 面向对象,实现namespace,class,继承,重载
Oct 29 Javascript
jQuery中:password选择器用法实例
Jan 03 Javascript
常用的Javascript数据验证插件
Aug 04 Javascript
基于JavaScript实现Json数据根据某个字段进行排序
Nov 24 Javascript
Jquery根据浏览器窗口改变调整大小的方法
Feb 07 Javascript
JavaScript ES6中const、let与var的对比详解
Jun 18 Javascript
angular中的cookie读写方法
Aug 02 Javascript
详解Vue双向数据绑定原理解析
Sep 11 Javascript
使用rollup打包JS的方法步骤
Dec 05 Javascript
JavaScript页面倒计时功能完整示例
May 15 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 preg_match_all结合str_replace替换内容中所有img
2008/10/11 PHP
php中的三元运算符使用说明
2011/07/03 PHP
php检查是否是ajax请求的方法
2015/04/16 PHP
PHP常用技巧汇总
2016/03/04 PHP
javascript学习笔记(十五) js间歇调用和超时调用
2012/06/20 Javascript
js 判断js函数、变量是否存在的简单示例代码
2014/03/04 Javascript
jQuery中get和post方法传值测试及注意事项
2014/08/08 Javascript
Jquery解析Json格式数据过程代码
2014/10/17 Javascript
JS中完美兼容各大浏览器的scrolltop方法
2015/04/17 Javascript
Bootstrap每天必学之导航条
2015/11/27 Javascript
深入理解JS中Number(),parseInt(),parseFloat()三者比较
2018/08/24 Javascript
小程序实现单选多选功能
2018/11/04 Javascript
vue实现手机端省市区区域选择
2019/09/27 Javascript
javascript中的相等操作符(==与===区别)
2019/12/21 Javascript
浅谈vue项目利用Hbuilder打包成APP流程,以及遇到的坑
2020/09/12 Javascript
Vue实现简易购物车页面
2020/12/30 Vue.js
Python和Ruby中each循环引用变量问题(一个隐秘BUG?)
2014/06/04 Python
Python调用C语言的方法【基于ctypes模块】
2018/01/22 Python
python 对txt中每行内容进行批量替换的方法
2018/07/11 Python
在Python中分别打印列表中的每一个元素方法
2018/11/07 Python
django小技巧之html模板中调用对象属性或对象的方法
2018/11/30 Python
python print输出延时,让其立刻输出的方法
2019/01/07 Python
详解通过变换矩阵实现canvas的缩放功能
2019/01/14 HTML / CSS
美国殿堂级滑板、冲浪、滑雪服装品牌:Volcom(钻石)
2017/04/20 全球购物
英国最大的化装舞会服装网站:Fancydress.com
2017/08/15 全球购物
10条PHP编程习惯
2014/05/26 面试题
财务经理的岗位职责
2013/12/17 职场文书
模具数控专业自荐信
2014/01/27 职场文书
网络编辑职责
2014/03/01 职场文书
社区党建工作汇报材料
2014/08/14 职场文书
入党积极分子党支部意见
2015/06/02 职场文书
客户答谢会致辞
2015/07/30 职场文书
离婚协议书范文2016
2016/03/18 职场文书
matplotlib之pyplot模块实现添加子图subplot的使用
2021/04/25 Python
解决pytorch读取自制数据集出现过的问题
2021/05/31 Python
Android Gradle 插件自定义Plugin实现注意事项
2022/06/16 Java/Android