请选择 进入手机版 | 继续访问电脑版

JavaWeb(5):AJAX与JSON

2018-11-9 09:24
14815
各位知乎的父老乡亲们,一个月没更新了,实在对不住。很久没写,一方面是这阵子学习上偷懒了,没有输入就没有输出。另一方面是上个月确实比较忙,直接从浙江忙到了北京。不知道加班加到秃头算不算工伤。
感慨啊,专栏人数快突破1k了...我从来没想过会有这么多人看我写的文字。虽然我时常觉得自己既写不了高深的,又无法保证能把简单的写对,但是作为自学的一种过程记录,不知不觉写到了现在。以后也尽量争取每个月能写一篇吧。当然,文章都是从我自己的疑惑出发,只能代表一部分初学者的困惑。
看标题大家就知道,今天主要想和大家聊聊AJAX和JSON(念作A贾克斯,不是阿贾克斯)。
在很长一段时间,我对AJAX和JSON的态度都不是很端正,导致我在敲JS代码时总是“见树不见林”,稀里糊涂的。想来,主要还是当初自学时对自己的定位出现了问题。
我学习JavaWeb时参考的是传智播客崔希凡老师的视频。崔老师的JavaWeb讲得非常出色,自然也包括对AJAX的讲解。从后端学习者的角度来说,讲得非常棒。最难得的是,在最后还演示了如何把原生的“ajax四步曲”封装成简洁易用的ajax方法(类似JQuery的$.ajax())。从我自己的感受来说,传智播客的资料并不是越新的视频就讲得越深。随着这几年互联网大爆发,新技术也层出不穷,为了顺应时代发展课程也越改越精炼,朝着实用和全面的方向去了,很多用不到又有难度的内容都被剔除。崔老师的视频是14年的,深度是够了,但是不够全面,比如崔老师的视频里就没有Bootstrap和jQuery。可以看出当时传智播客在Java培训中对前端的重视程度是不如现在的,可能老师们的想法和我当初一样,觉得前端主要看得懂就好了。
只学了原生的AJAX(繁琐而且很难),又压根没弄明白JSON是什么,用来干啥,我就直接硬着头皮往后学了。等工作时,发现自己对jQuery的ajax以及JSON一无所知。
我在知乎的一个回答中曾经调侃很多初学Java的朋友很天真,把自己当成后端工程师,认为自己出来就是写写ssm,压根不考虑HTML/CSS/JS。其实说的是我自己。正是基于这种观念,我学习Java时,遇到前端的知识,都是蜻蜓点水...
AJAX是个啥?

说到AJAX,不得不提到一门编程语言——JavaScript。JavaScript诞生于1995年。在那个绝大多数用户都在使用调制解调器上网的时代,用户填写完一个表单点击提交,需要等待几十秒,完了服务器反馈给你说某个地方填错了......在当时如果能在客户端完成一些基本的验证绝对是令人兴奋的。所以,起初JS的主要目的是处理以前由服务器端负责的一些表单验证。
JavaWeb(5):AJAX与JSON-1.jpg
网速本身慢,发过去1分钟,结果你告诉我密码不符合规则,真的是表面笑嘻嘻,心里mmp。
当时走在技术革新最前沿的Netscape(网景)公司,决定着手开发一种客户端语言,用来处理这种简单的验证。当时就职于Netscape公司的布兰登·艾奇开始着手计划将1995年2月发布的LiveScript同时在浏览器和服务器中使用。为了赶在发布日期前完成LiveScript的开发,Netscape与Sun公司成立了一个开发联盟。而此时,Netscape为了搭上媒体热炒Java的顺风车,临时把LiveScript改名为JavaScript,所以从本质上来说JavaScript和Java没什么关系。
JavaWeb(5):AJAX与JSON-2.jpg
当然,时至今日5G都快出来了。家用宽带100M也是稀松平常。即使全部交给服务器端校验,也丝毫不影响用户体验。因为网实在太快了。如果当年JS止步不前,仅仅满足于做前端校验不思进取,那么它早就灭亡了。实际上,当年正是AJAX的出现,革新了网页交互的格局,把JS推向了人生巅峰。现在JS已经是GitHub提交量最多的语言,它能做的事情也越来越多,甚至干起了服务端(node.js)。
AJAX不是一门编程语言,只是一种技术。它和JS有关,也就是说它的代码运行在客户端(因为JS运行在浏览器),而不是服务端。
AJAX的全称是Asynchronous JavaScript And XML(异步的JS和XML),说明当初这门技术设想的最佳拍档是JS和XML。很可惜,现在大家更倾向于JS+JSON。所以,也有人认为AJAX应该干脆改名为AJAJ得了(Asynchronous JavaScript And JSON)。
JavaWeb(5):AJAX与JSON-3.jpg
这就是AJAX的能力!
我还没点“百度一下”,仅仅是在输入框中输入几个字母,服务器就根据我输入的内容响应回可能的备选关键字!
关于“同步”与“异步”,目前可以粗浅地理解为:
同步:我填完所有表单后,点击“提交”按钮,所有内容才会一起发给服务器!
异步:我刚填完“账号”,点击填写“密码”时,页面就让JS拿着“账号”去让服务器校验了。那么我们填写“密码”时就知道刚才填写的“账号”是不是重复/错误的。
JavaWeb(5):AJAX与JSON-4.jpg
这里简单说一下JS实现异步请求的原理:原先JS的请求由JS引擎负责,同步请求依赖JS引擎。当JS发起一个请求时,在请求未接收响应前它不能做任何事,处于等待状态,效率很低。而异步请求是由JS委托AJAX引擎(XMLHttpRequest对象)发起的,请求交给AJAX引擎后,JS引擎就可以抽身做别的事,等到AJAX引擎拿到响应给它后,它再渲染数据显示即可!(老板让秘书去买咖啡,自己继续工作)
JavaWeb(5):AJAX与JSON-5.jpg
JavaWeb(5):AJAX与JSON-6.jpg
好,到这里,我们虽然还没有深入了解AJAX具体如何落实到代码上实现异步请求,但也算有了初步印象。只是这JSON,至今仍不明朗。它到底是个啥?
JSON是个啥?

我们先来绕个弯。还记得在学习JavaSE的IO流时,我们曾经学过序列化流吗?分为序列化流和反序列化流。通过这两种流可以实现对象序列化和反序列化。那么何谓对象序列化?对象序列化是将对象状态转化为可保持或传输的过程。一般的格式是与平台无关的二进制流。可以将这种二进制流持久保存在磁盘上,也可以通过网络将这种二进制流传输到另一个网络节点。
有点懵?来捋一捋。
首先,我们要明白,对象一般只在内存中“存活”。我们在程序中new了一个对象,当我们关闭电脑时,只要内存一断电,对象就会消失。如果希望下次打开时还能再现这个对象,必须在关机前将此对象从内存中取出保存在硬盘中,也就是持久化。而所谓的对象序列化,可以有两种用途,其中一种便是将对象通过二进制流在硬盘中持久化(作为文件)。
JavaWeb(5):AJAX与JSON-7.jpg
让我想起《三体》中的三体游戏。人们在乱纪元脱水,变成一张张人皮存在仓库中。等到恒纪元到来,剩余的活人把人皮搬到河中,人皮吸水后又变成活人。
序列化的另一种用途,则是用作不同工程间的远程通讯。对于一般的SSM应用(单一系统),是不需要将对象序列化的。但一旦涉及远程调用,或者分布式系统,一个系统调用另一个系统的服务时,POJO对象必须支持序列化。这样,在一个系统中序列化后,经过网络传输到达另一个系统时,可以通过反序列重构对象,使得在这个系统也可以使用这个对象。怎么做到让对象序列化?只要让POJO类实现Serializable接口就可。
JavaWeb(5):AJAX与JSON-8.jpg
JavaWeb(5):AJAX与JSON-9.jpg
为什么我之前创建POJO类时不用implements Serializable接口?因为以前做的项目,都是单系统,也就是部署在单一服务器,所有的调用都是在这个服务器上的。
JavaWeb(5):AJAX与JSON-10.jpg
整个应用,都是在同一个服务器上,不管哪一层,相互调用都是在同一片内存中,直接传Java对象,不需要序列化为二进制数据。
所谓的序列化,实质上是将内存中的对象变为二进制数据(流)传到遥远的另一台服务器,在该服务器上再由二进制数据转为内存中的对象。典型应用是分布式系统。
JavaWeb(5):AJAX与JSON-11.jpg
分布式则是一个服务器的系统调用另一个服务器的系统,不同电脑间,我必须把我的Java对象序列化成二进制数据通过一根网线连到另一台电脑去。关于分布式,可以参考传智的第二个大项目,电商项目
哦,似乎挺像那么回事。可,这个和JSON有什么关系?
大家有没有想过,Java希望别人能用自己的对象,搞了个序列化,难道我JS就不能有这需求吗?我...我...我希望后端能用我的JS对象!
好吧,这纯粹是瞎几把扯。后端是不可能直接用前端的对象的。但是,这个设想还是不错的。我可以通过双方约定的某种数据格式,把JS对象按此格式传到后端,后端再通过某种方式把这个格式的数据转成Java对象。JS对象→某种格式传输→Java对象,通过这个过程,也相当于在后端使用JS对象了,当然啦,严格意义上Java后台是不可能使用JS对象的。
现在问题在于,所谓的“某种格式”到底是哪种格式呢?
我们在学习JavaWeb时,由于前段课程还没学习数据库,曾经用xml文件充当过“数据库”。
JavaWeb(5):AJAX与JSON-12.jpg
这说明XML是可以用来表示对象的。这也是为什么当初AJAX会选择XML作为数据交换格式。但是由于JS本身对JSON支持很好(JSON就是JS的人),在JS前端(主场作战)比XML在解析方面更有优势,轻量且效率高。比如你要取person的age,在把JSON串转为JS对象后,可以直接person.age得到!所以在前后端交换数据方面,JSON毫无疑问是最佳选择。
JavaWeb(5):AJAX与JSON-13.jpg
作为传输格式,当然有“一来一回”两处应用,但是一般请求时习惯key/value格式,响应则是JSON格式
但XML作为配置文件的首选标记语言,在自己的领域又甩JSON一条街。因为JSON表示嵌套逻辑关系时显得很凌乱,要不断地在一个值里面再塞入另一个值。不如XML直观。
JavaWeb(5):AJAX与JSON-14.jpg
JSON作为一种轻量级的数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据,易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
也就是说,不管你后台用Java/PHP/C#,都可以用JSON交互数据。而且不止web,Android和IOS也可通过JSON和后端交换数据。JSON作为一种数据交换格式,是独立于特定语言之外的。
再看JSON

虽然上面说了一大堆,但是可能部分初学者心里还是有很多疑问。没关系,这一小节会继续展开。
JSON的英文全称是JavaScript Object Notation,也就是JS对象标记法
很多朋友可能会和我一样被这个概念搞得稀里糊涂。比如你们在看视频时,会经常听到“JSON是一种数据交换格式”,然后恍然大悟:哦,JSON是一种格式呀。但是看着看着,又听老师说:好,来看一下,这个就是JSON对象。
JavaWeb(5):AJAX与JSON-15.jpg
不是说JSON是一种数据交换格式吗?怎么格式还有对象?
视频中你会看到老师介绍下面的内容:
  1. [/code]我擦嘞!这特么不是JS的字面量对象吗?
  2. [code]
复制代码
所以,所谓的JSON对象和JS对象有啥关系啊?JSON到底是什么?啊啊啊啊!!头好大。
其实,按我的理解,压根就没有什么JSON对象!JSON从始至终只是一种数据交换格式,它是一套规范。它的载体是字符串,而不是什么对象。为什么JSON格式会选择字符串作为表现的载体?因为字符串在某种意义上是通用的。不管是JS,还是Java/PHP/C#,都是支持字符串的。用对象则不合适,JS有JS对象,Java有Java对象...如果是字符串就很好办,大家都有这个类型。而且各个语言都提供了解析JSON字符串到自己对象的方法。
    后端传给前端的JSON串在前端解析后可能是数组或者对象。其中,解析后的对象往往被人们称为JSON对象(如果是数组,也是JSON对象数组,即元素是JSON对象)。前端传给后端的JSON串则转化为对应后端语言的对象,比如Java的类对象。
JavaWeb(5):AJAX与JSON-16.jpg
但我们要清楚,其实,前端解析后的JSON对象就是JS对象而已。
JavaWeb(5):AJAX与JSON-17.jpg
JSON,载体是字符串,可以用字符串表示对象/数组
JavaWeb(5):AJAX与JSON-18.jpg
JSON串表示对象,解析为对象
JavaWeb(5):AJAX与JSON-19.jpg
JSON串表示数组,解析为数组
但是现在网上的培训视频,其实各有各的说法。会把JSON串(JSON格式的载体)解析后的对象称为JSON对象。所以广义上来讲,干脆认为JSON有两种,一种是语法更为严格的JS对象(本质还是JS对象),另一种是JSON格式的字符串吧!

JSON对象:符合JSON格式的JS对象
  1. [/code]上面的person对象之所以被称为JSON对象,只是因为这个JS对象符合JSON格式。相比来说,JSON的语法要比JS更严格。但是要注意,有些情况下有人会把JS对象也叫做JSON对象,而且代码执行时也能成功。虽然不是很规范,但是你要能听得懂。而且我们要尽量遵守规范。
  2. [b]JSON字符串:符合JSON格式的字符串[/b]
  3. 我们常说的JavaScript中的字符串是单引号或者双引号引起来的。
  4. [code]
复制代码
从第三行代码可以看出person本质是个字符串,只是这个字符串符合JSON格式,所以称为JSON字符串。

那么JSON格式有什么要求呢?以下是我能找到的格式要求:
    对象表示为键值对,键必须加双引号值不能是方法函数,不能是undefined/NaN数据由逗号分隔花括号保存对象方括号保存数组
上面的JSON对象和JSON字符串都符合上述规范,所以原本普通的JS对象和字符串被称为JSON对象和JSON字符串。可以这么说:JSON的语法比JS对象语法更为严格,可以认为是JS对象语法的子集。
JavaWeb(5):AJAX与JSON-20.jpg
结论:
    JSON是一种数据格式,载体是字符串,因为字符串是通用的广义上,JSON对象是语法更为严格的JS对象JSON串必须符合JSON格式
另外,在实际使用AJAX时,data参数值的键加不加双引号都是可以的。(参见下一节的代码格式)
AJAX与JSON的代码格式

既然要用ajax异步请求,那么代码格式是怎样的呢?
JavaWeb(5):AJAX与JSON-21.jpg
前端表单
JavaWeb(5):AJAX与JSON-22.jpg
ajax-key/value格式,其中第一、第二种格式是JS对象(你也可以认为是JSON对象),但这种请求方式,其实在后端看来都是key/value形式的

JavaWeb(5):AJAX与JSON-23.jpg
ajax-JSON格式。JSON的载体是字符串,此时要指定contentType:application/json;charset=utf-8,以告诉后端程序我传的是JSON格式,方便后端应对
总结起来就是:
    请求时有两种选择:key/value格式 or JSON串请求时key/value格式比JSON串常用,因为要用JSON串的话,在前端还要把对象转成串,麻烦响应时都返回JSON串。ajax中dataType:"json"的意思是:指定按什么格式解析返回值。因为返回的是JSON串,自然要按JSON解析,否则会出错。
大家会发现,我们在上面讲了半天的JSON,其实到头来,就是两种:
请求
JSON串(不常用)
key/value(JSON对象/JS对象/参数拼接)(常用)
响应
JSON串(常用)

上面的图只画了表单和对应的几种ajax格式,都是讲前端如何发送,没有说后端如何处理。
其实后端的转化主要涉及
    接收前端请求:(JSON串/key-value格式)→Java对象响应:Java对象→JSON串
接收key/value格式的请求大家都很熟悉了,就是根据键取值,而且在SpringMVC中都是自动封装到形参里的。就不说了。
如何接收JSON串呢?在SpringMVC框架中,提供了@RequestBody注解来将JSON格式的请求参数自动封装成Java对象。
也就是说不论前端传key/value格式还是JSON串,都能转为Java对象。那么一系列处理后,如何转为JSON串返回呢?在SpringMVC框架中,还提供了@ResponseBody注解来将Java对象转为JSON串返回给前端。
SpringMVC之所以能完成自动转化,主要是依靠JackSon第三方jar包。也就是说,如果没有SpringMVC,我们也可以引入JackSon帮我们转换格式。
***特别注意下Controller里的方法,加不加@ResponseBody的区别(以return "index"为例):
    不加注解,会把return的字符串解析为视图地址,跳转到对应页面加了注解,不跳转页面,会把return的字符串当做数据返回
JavaWeb(5):AJAX与JSON-24.jpg
如果是key/value格式,就不用加@RequestBody,SpringMVC会自动把参数封装到形参对象中
再看AJAX

夜深了,不打算再细写。其实jQuery的$.ajax()在使用上是很简单的。只是大家可能会对它的形式很困惑。
JavaWeb(5):AJAX与JSON-25.jpg
仔细看,$.ajax()里传的是{xxx:xxx, xxx:xxx, ...}的形式。崔老师在视频的最后有试着实现一个类似的ajax方法。可以看看。看完,多少会觉得这个奇怪的形式其实并不奇怪。
JavaWeb(5):AJAX与JSON-26.jpg
明天有时间再完善,并把参考的资料列出来。另外,关于什么远程调用序列化以及json的理解,其实心里是存疑的。另外对于ajax方法中,data参数类型可以是哪几种,有何区别,网上没找到详细的解释,希望有不同见解的朋友可以指出。谢谢大家,晚安。2018-7-1 23:04:59
参考视频(观看时按顺序即可):
1.黑马32期JavaWeb day22-AJAX,郝强勇老师
链接:https://pan.baidu.com/s/1iNZQ94vUzP7sWCUpK_VLbQ 密码:mted
2.黑马前端AJAX视频
【黑马程序员】Ajax从零入门到精通(part 1)_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili
3.传智JavaWeb视频 day23-AJAX,崔希凡老师
链接:https://pan.baidu.com/s/10YGCII8_O6Z5VWxR-IBLsg 密码:pno1
4.传智SpringMVC视频 day2(视频11~13),燕青老师
链接:https://pan.baidu.com/s/1bvxk6_Cb0Zd75W_ko9HICg 密码:psnl
5.黑马前端就业班JS基础视频(JS引入做得不好,但绝对深入浅出)
链接:https://pan.baidu.com/s/1G40rZFVAL9vZlvVzSHJ0ag 密码:9usw
6.尚硅谷JS基础视频(最后一个视频),李立超老师(讲到了JSON串与JSON对象转换)
链接:https://pan.baidu.com/s/1mYEQKJp2rxylKo2tGNSi2Q 密码:5384
参考博文:
Json对象和Json字符串的区别 - ilinux_one - 博客园
Ajax请求($.ajax()为例)中data属性传参数的形式 - CSDN博客
最后,这是本专栏我写得最没底的一篇文章。因为不论JS还是JSON,我其实都不熟悉。仅仅是现学现卖,不知道有多少纰漏。还请过往的朋友斧正。
分享到 :
0 人收藏

15 个回复

倒序浏览
只剩余温  高级会员 | 2018-11-9 09:24:26
我对崔老师的java web课程印象深刻,讲的真的透彻
瘾。  高级会员 | 2018-11-9 09:24:26
写的通俗易懂
﹍擱淺′  限制会员 | 2018-11-9 09:24:26
小伙子,火力依然很猛啊
葬婲  中级会员 | 2018-11-9 09:24:26
不是很简单的$.get(或者post){请求路径,参数,回调函数,返回格式}吗?
我是这么理解的。
誮落  中级会员 | 2018-11-9 09:24:26
Jquery对ajax的封装可以看成有三层。最底层是$.ajax,再上层是$.get和$.post,最上层是$.getscript getjson之类的
烈酒烫喉  中级会员 | 2018-11-9 09:24:26
专栏还在更新就好。继续啊(ノ๑`ȏ´๑)ノ︵⌨
风情  中级会员 | 2018-11-9 09:24:26
通俗易懂,赞一个
笑靥  高级会员 | 2018-11-9 09:24:26
老哥用的啥编译器哈?推荐下呗
荷尔蒙的诱惑  中级会员 | 2018-11-9 09:24:26
用的eclipse。截图那个不是我的,是视频里截的。前端的IDE
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|翁笔

© 2001-2018 Wengbi.com

返回顶部