通过实例解析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 cookie操作类的实现代码小结附使用方法
Jun 02 Javascript
javascript+canvas制作九宫格小程序
Dec 28 Javascript
JavaScript正则表达式中的ignoreCase属性使用详解
Jun 16 Javascript
基于JavaScript实现在新的tab页打开url
Aug 04 Javascript
jQuery+ajax读取并解析XML文件的方法
Sep 09 Javascript
Vue.js组件tabs实现选项卡切换效果
Dec 01 Javascript
jQuery多选框选择数量限制方法
Feb 08 Javascript
js实现三级联动效果(简单易懂)
Mar 27 Javascript
Vue项目中引入外部文件的方法(css、js、less)
Jul 24 Javascript
基于vue和react的spa进行按需加载的实现方法
Sep 29 Javascript
详解angular2 控制视图的封装模式
Dec 27 Javascript
原生JS实现多条件筛选
Aug 19 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
重料打造自己的“宝马”---第三代
2021/03/02 无线电
ThinkPHP有变量的where条件分页实例
2014/11/03 PHP
PHP ajax 异步执行不等待执行结果的处理方法
2015/05/27 PHP
PHP对文件夹递归执行chmod命令的方法
2015/06/19 PHP
php tpl模板引擎定义与使用示例
2019/08/09 PHP
利用js的Node遍历找到repeater的一个字段实例介绍
2013/04/25 Javascript
require.js深入了解 require.js特性介绍
2014/09/04 Javascript
HTML5实现留言和回复页面样式
2015/07/22 Javascript
jQuery实现仿美橙互联两级导航菜单效果完整实例
2015/09/17 Javascript
浅谈JavaScript对象的创建方式
2016/06/13 Javascript
javascript 操作cookies详解及实例
2017/02/22 Javascript
一个Js文件函数中调用另一个Js文件函数的方法演示
2017/08/14 Javascript
jQuery选择器特殊字符与属性空格问题
2017/08/14 jQuery
Angular搜索 过滤 批量删除 添加 表单验证功能集锦(实例代码)
2017/10/25 Javascript
JavaScript 对引擎、运行时、调用堆栈的概述理解
2018/10/22 Javascript
Nodejs中获取当前函数被调用的行数及文件名详解
2018/12/12 NodeJs
ES6常用小技巧总结【去重、交换、合并、反转、迭代、计算等】
2019/12/21 Javascript
vue中template的三种写法示例
2020/10/21 Javascript
详解Python中表达式i += x与i = i + x是否等价
2017/02/08 Python
python中reload(module)的用法示例详解
2017/09/15 Python
Python使用matplotlib绘制三维参数曲线操作示例
2019/09/10 Python
TensorFLow 不同大小图片的TFrecords存取实例
2020/01/20 Python
利用Python裁切tiff图像且读取tiff,shp文件的实例
2020/03/10 Python
Tensorflow全局设置可见GPU编号操作
2020/06/30 Python
Python 爬虫性能相关总结
2020/08/03 Python
Python实现中英文全文搜索的示例
2020/12/04 Python
Boolean b = new Boolean(“abcde”); 会编译错误码
2013/11/27 面试题
高中毕业生自我鉴定例文
2013/12/29 职场文书
学校安全生产承诺书
2014/05/23 职场文书
2015年销售部工作总结范文
2015/04/27 职场文书
红色经典观后感
2015/06/18 职场文书
2016继续教育培训学习心得体会
2016/01/19 职场文书
《地震中的父与子》教学反思
2016/02/16 职场文书
python tqdm用法及实例详解
2021/06/16 Python
redis的list数据类型相关命令介绍及使用
2022/01/18 Redis
pytorch中的 .view()函数的用法介绍
2022/03/17 Python