谈谈Ajax

Posted 挑战者V

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了谈谈Ajax相关的知识,希望对你有一定的参考价值。

昨天还没有谈完,今天做一个了解。

首先还是以错误,来讲述。

 

一、AJax常见错误

Ajax常见的错误,除了昨天列举的之外。还有就是如下状态码:

405,请求类型错误,比如请求是POST,你却用GET,通常出现这种情况是在SpringMVC中的@RequestMapping,有使用SpringMVC经验的小伙伴们都知道,@RequestMapping默认的请求方式为GET。如果你因为复制粘贴没有仔细检查,在调试Ajax的时候就会出现405状态码。当然了,你没有通过Ajax的调试方式,通常就会直接走error,并不会出现405状态码的提示。一般情况下,出现这种问题的概率非常少,因为还有postman。通过postman进行接口测试,一般情况下,如果你的情况不对,直接提示不支持该请求。

 

415,服务器无法处理请求附带的媒体格式。因为你在Ajax中加入了contentType并指定了媒体格式为application/json;

如果你的参数列表中没有加入@RequestBody就会出现415。

@RequestBody通常用来处理contentType不是默认的application/x-www-form-urlcode编码的内容。比如说application/json和application/xml,一般情况下处理application/json。

例如:

技术分享图片

403,这个通常就是你的请求参数与接收参数不一致,比如createDate在前台是String类型,但是后台你却用Date类型接收,就会出现这种问题。

一般情况下,当参数比较多的时候,建议使用对象(参数三个以上,就建议使用对象比较好)。

 

500,这个通常就是服务端代码有问题了。这个就要根据具体的调试情况来看了。比如空指针或者是类型转换异常等等。

 

二、如何调试Ajax

比如我通过postman来测试,没有发现问题,并不代表web端异步请求没有问题。比如我在上面说到的Ajax常见错误,这些常见错误,很少能通过postman来发现的。因为开发人员,会因为疏忽大意,懒得测试(单元测试)等可能的意外原因导致问题的出现。又或者是我通过单元测试发现没问题,并不代表web开发请求url或者是安卓那边请求没问题。

比如:

技术分享图片

 

这段代码正常返回的集合数据是不带斜杠的,而web请求却带斜杠。

这是因为String的原因,如果将其返回值换为Object或者并将其toJSONString()改为toJSON()就可以得到正常的json数据而不是带斜杠的字符串数据。

虽然说,带斜杠可以通过jQuery的eval、安卓那边的replace方法解决,但是最好还是不要绕一大圈。

调式的手段,主要是在error的function加上对应的三个参数XMLHttpRequest、textStatus、errorThrown等。

技术分享图片

弹出状态码的是XMLHttpRequest.status,正常的状态码应为200。

 

状态码详解如下:

1**:请求收到,继续处理
2**:操作成功收到,分析、接受
3**:完成此请求必须进一步处理
4**:请求包含一个错误语法或不能完成
5**:服务器执行一个完全有效请求失败
100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本
200——交易成功
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成了部分用户的GET请求
300——请求的资源可在多处得到
301——删除请求数据
302——在其他地址发现了请求数据
303——建议客户访问其他URL或访问方式
304——客户端已经执行了GET,但文件未变化
305——请求的资源必须从服务器指定的地址得到
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除
400——错误请求,如语法错误
401——请求授权失败
402——保留有效ChargeTo头响应
403——请求不允许
404——没有发现文件、查询或URl
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问
407——类似401,用户必须首先在代理服务器上得到授权
408——客户端没有在用户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且无进一步的参考地址
411——服务器拒绝用户定义的Content-Length属性请求
412——一个或多个请求头字段在当前请求中错误
413——请求的资源大于服务器允许的大小
414——请求的资源URL长于服务器允许的长度
415——请求资源不支持请求项目格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求
500——服务器产生内部错误
501——服务器不支持请求的函数
502——服务器暂时不可用,有时是为了防止发生系统过载
503——服务器过载或暂停维修
504——关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较长
505——服务器不支持或拒绝支请求头中指定的HTTP版本

 

至于XMLHttpRequest.readyState说的是AJax异步请求服务器的过程(一共五个过程):

 

(0)未初始化
此阶段确认XMLHttpRequest对象是否创建,并为调用open()方法进行未初始化作好准备。值为0表示对象已经存在,否则浏览器会报错--对象不存在。


(1)载入
此阶段对XMLHttpRequest对象进行初始化,即调用open()方法,根据参数(method,url,true)完成对象状态的设置。并调用send()方法开始向服务端发送请求。值为1表示正在向服务端发送请求。


(2)载入完成
此阶段接收服务器端的响应数据。但获得的还只是服务端响应的原始数据,并不能直接在客户端使用。值为2表示已经接收完全部响应数据。并为下一阶段对数据解析作好准备。


(3)交互
此阶段解析接收到的服务器端响应数据。即根据服务器端响应头部返回的MIME类型把数据转换成能通过responseBody、responseText或responseXML属性存取的格式,为在客户端调用作好准备。状态3表示正在解析数据。


(4)完成
此阶段确认全部数据都已经解析为客户端可用的格式,解析已经完成。值为4表示数据解析完毕,可以通过XMLHttpRequest对象的相应属性取得数据。
概而括之,整个XMLHttpRequest对象的生命周期应该包含如下阶段:
创建-初始化请求-发送请求-接收数据-解析数据-完成

 

 

用个例子说明:

比如我给远方的一个朋友打电话,

第一,我必须要有手机,没有手机怎么打电话,对应(0);

第二,我要将我说的第一句话传达给他,这是(1);

第三,我说的话已经传达给他了,这是(2);

第四,他需要理解我话中所表达的意思是什么,这是(3);

第五,他已经理解的我话的意思,这是(4);

 

也许这个例子表达的不是特别恰当,但是我觉得已经可以比较好的说明异步请求服务的过程和readyState的含义。

 

 

三、Ajax中的参数含义(以jQuery中的$.ajax为例)

1.url
  要求为String类型的参数,(默认为当前页地址)发送请求的地址

2.type
  要求为String类型的参数,请求方式(postget)默认为get。注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持。

3.timeout
  要求为Number类型的参数,设置请求超时时间(毫秒)。此设置将覆盖$.ajaxSetup()方法的全局设置。

4.async
  要求为Boolean类型的参数,默认设置为true,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为false。注意,同步请求将锁住浏览器,用户其他操作必须等待请求完成才可以执行。

5.cache
  要求为Boolean类型的参数,默认为true(当dataType为script时,默认为false),设置为false不会从浏览器缓存中加载请求信息

6.data
  要求为ObjectString类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格式get请求中将附加在url后。防止这种自动转换,可以查看  processData(防止自动转换)选项。对象必须为key/value格式,例如{foo1:"bar1",foo2:"bar2"}转换为&foo1=bar1&foo2=bar2。如果是数组,JQuery将自动为不同值对应同一个名称。例如{foo:["bar1","bar2"]}转换为&foo=bar1&foo=bar2。

7.dataType
  要求为String类型的参数,预期服务器返回的数据类型。如果不指定,JQuery将自动根据http包mime信息返回responseXML或responseText,并作为回调函数参数传递。可用的类型如下:
  xml:返回XML文档,可用JQuery处理。
  html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。
  script:返回纯文本javascript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一个域下),所有post请求都将转为get请求。
  json:返回JSON数据。
  jsonp:JSONP格式。使用SONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。
  text:返回纯文本字符串。

8.beforeSend
  这个参数主要是为了在向服务器发送请求前,执行一些操作。要求为Function类型的参数,发送请求前可以修改XMLHttpRequest对象的函数,例如添加自定义HTTP头。在beforeSend中如果返回false可以取消本次ajax请求。XMLHttpRequest对象是惟一的参数。
            function(XMLHttpRequest){
               this;   //调用本次ajax请求时传递的options参数
            }
9.complete
  要求为Function类型的参数,请求完成后调用的回调函数(请求成功或失败时均调用)。参数:XMLHttpRequest对象和一个描述成功请求类型的字符串。
          function(XMLHttpRequest, textStatus){
             this;    //调用本次ajax请求时传递的options参数
          }

10.success

  要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。
         (1)由服务器返回,并根据dataType参数进行处理后的数据。
         (2)描述状态的字符串。
         function(data, textStatus){
            //data可能是xmlDoc、jsonObj、html、text等等
            this;  //调用本次ajax请求时传递的options参数
         }

11.error:
要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数,即XMLHttpRequest对象、错误信息、捕获的错误对象(可选)。ajax事件函数如下:
       function(XMLHttpRequest, textStatus, errorThrown){
          //通常情况下textStatus和errorThrown只有其中一个包含信息
          this;   //调用本次ajax请求时传递的options参数
       }

12.contentType
要求为String类型的参数,当发送信息至服务器时,内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。

13.dataFilter
要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataType参数。函数返回的值将由jQuery进一步处理。
            function(data, type){
                //返回处理后的数据
                return data;
            }

14.dataFilter
要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataType参数。函数返回的值将由jQuery进一步处理。
            function(data, type){
                //返回处理后的数据
                return data;
            }

15.global
要求为Boolean类型的参数,默认为true。表示是否触发全局ajax事件。设置为false将不会触发全局ajax事件,ajaxStart或ajaxStop可用于控制各种ajax事件。

16.ifModified
要求为Boolean类型的参数,默认为false。仅在服务器数据改变时获取新数据。服务器数据改变判断的依据是Last-Modified头信息。默认值是false,即忽略头信息。

17.jsonp
要求为String类型的参数,在一个jsonp请求中重写回调函数的名字。该值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,例如{jsonp:‘onJsonPLoad‘}会导致将"onJsonPLoad=?"传给服务器。

18.processData

要求为Boolean类型的参数,默认为true。默认情况下,发送的数据将被转换为对象(从技术角度来讲并非字符串)以配合默认内容类型"application/x-www-form-urlencoded"。如果要发送DOM树信息或者其他不希望转换的信息,请设置为false。

19.scriptCharset
要求为String类型的参数,只有当请求时dataType为"jsonp"或者"script",并且type是GET时才会用于强制修改字符集(charset)。通常在本地和远程的内容编码不同时使用。


上述的1,2,6,7,10,11,12是我开发过程中比较常用的。其他的几乎很少用。

 

四、SSM框架与Ajax三种方式(主要说明参数传递和接收)

第一种,直接在参数列表中写。

技术分享图片

 

优点,直接指明参数类型即可,确保前端和后台的参数类型一致,就可以接收并处理;

缺点,当参数过多时,建议使用对象,不然随着业务改动,可能需要对象参数列表进行修改,导致出现一些不必要的异常,比如415状态码和403状态码异常或者是500状态码异常。

 

第二种,通过HttpServletRequest

技术分享图片

 


第三种,使用Map

技术分享图片

注意,使用Map的话,记得在参数列表中加上@RequestParam,否则会发现参数无法传过来。

 

这三种如果都用于Ajax异步交互,其本质可以发现都是通过获取键来得到值。

当然了,再本质,就是基于HTTP请求。

 












































































































以上是关于谈谈Ajax的主要内容,如果未能解决你的问题,请参考以下文章

谈谈我对AJAX的理解

来谈谈ajax

AJAX请求真的不安全么?谈谈Web安全与AJAX的关系。

AJAX请求真的不安全么?谈谈Web安全与AJAX的关系

谈谈axios配置请求头content-type

谈谈 ES6 的 Promise 对象