通过 JQuery 发起 AJAX 请求
1. 使用 jQuery 实现 AJAX
在 JavaScript 中直接使用 XMLHttpRequest 类实现 Ajax 技术仍显得十分繁琐,而 jQuery 吸引人的原因之一就是它提供了大量关于 Ajax 的工具方法。
由于各种浏览器对 XMLHttpRequest 对象的实现有些不同,所以要通过 JavaScript 来实现原生的 AJAX 功能需要编写大量的平台相关的判断处理代码来处理同一份代码的跨平台问题。这大大降低了开发效率和出错概率。而现今通用的解决方案是使用 jQuery 库来实现 AJAX 功能。jQuery 库封装了各个平台的 AJAX 功能,对外提供了统一的接口。
常见的四个工具方法
var str = $.param(obj); // 对象转请求参数字符串(query-string)
var str = $('#form_id').serialize(); // 表单数据转请求参数字符串
var str = JSON.stringify(obj); // 对象转 json 格式字符串(json-string)
var obj = JSON.parse(json_str); // json 格式字符串转对象
-
query-string(请求参数字符串)格式更常见,配合 content-type:appliction/x-www-form-urlencoded 使用。其格式形如:
[email protected]
-
json-string 格式较少见一些,通常是有些在 AJAX 请求中会见到,配合 content-type:application/json 使用。其格式形如:
{"name": "tom, "age":20, "email": "[email protected]"}
核心方法:$.ajax()
$.ajax() 方法是 jQuery 最底层的 AJAX 实现,也就是说 jQuery 的其他 AJAX 方法(例如:$.get() 和 $.post())都是基于此方法实现的。使用的语法如下:
$.ajax(options)
该方法只有一个参数,但这个参数包含了 $.ajax() 方法所需要的请求设置以及回调函数等信息,参数以 key-value 的形式存在,所有参数都是 可选的 。
$.ajax() 参数很多,其中最常见的有:
参数名称 | 参数类型 | 参数说明 |
---|---|---|
url | string | 默认值当前页地址,发送请求的地址 |
type | string | 默认值为 get,表示请求方式。除了 post 外,还支持 put 和 delete(依赖于浏览器) |
contentType | string | 默认值为 application/x-www-form-urlencode 。这个属性表示发送给服务器的内容的编码类型。默认值适用大多数情况。 |
data | string 或 对象 |
发送到服务器的请求参数。本质上 $.ajax() 需要的是字符串,如果你传入的是 Object,jQuery 会将它自动转换成 Query String 格式(?aaa=bbb&ccc=ddd 形式)。 |
dataType | String | 预期服务器返回的数据类型。如果不指定,jQuery 会根据 HTTP 中的 MIME 信息进行推测。常见有:xml 、html 、json 、Text |
success | function | 请求成功(响应状态码为 200)后调用此函数。参数是由服务器返回的数据(具体数据类型与 dataType 有关);描述状态的字符串 |
async | boolean | 默认 true,表示异步请求。 设置为 false 则表示使用同步方式发起请求。 |
$.ajax() 方法「有且仅有 2 种」标准使用形式:
::: details 标准使用形式一(Query String)
$.ajax({
url: '请求路径',
type: "get or post",
contentType: 'application/x-www-form-urlencoded',
data: 'Query String 形式的请求参数字符串',
success: function(result) {
...
}
});
::: details 上述形式,有一种简写形式:
$.ajax({
url: '请求路径',
type: "get or post",
data: 对象,
success: function(result) {
...
}
});
:::
这里 $.ajax 方法帮我们简化了 2 处地方:
省略了 contentType,缺省时,它的默认值就是 application/x-www-form-urlencoded
data 属性本来需要一个 Query String,我们传的是一个对象。$.ajax 方法内部会自己调用 $.param 方法将对象转换为 Query String 。
::: details 标准使用形式二(JSON String)
$.ajax({
url: '请求路径',
type: "post",
contentType: 'application/json',
data: 'JSON String 形式的请求参数字符串',
success: function(result) {
...
}
});
除此之外,$.ajax()
方法,还可以设定 beforeSend(提交前回调)、error(请求失败后回调)、success(请求成功返回后回调)以及 complete(请求完成回调,无论成功失败后 )回调函数。
其他参数:
参数名称 | 参数类型 | 参数说明 |
---|---|---|
beforeSend(XHR) | function | 发送前回调函数。可以修改 xmlHttpRequest 对象。 如果返回false,则可以取消本次请求。 XMLHttpRequest 对象是该方法唯一参数 |
context | object | 用于设置 AJAX 回调函数的上下文。也就是说,让回调函数内的 this 指向这个对象。 如果没有设置它,那么回调函数中的 this 指向的是本次 AJAX 请求时传递的 options 参数。 |
error | function | 失败时调用此函数 有三个参数:XMLHttpRequest对象、错误信息、可选的异常对象 |
complete(XHR, TS) | function | 请求完成后调用此函数(成功或失败都调用)。参数::XMLHttpRequest对象 和 一个描述请求类型的字符串 |
timeout | number | 设置请求超时时间(毫秒) |
.post() 方法
$.get() 和 $.post() 方法是对 $.ajax() 方法的包装,专门用于发送 GET 请求和 POST 请求。
具体细节略。我个人还是比较偏好 $.ajax() 方法。
2. 一个常见的碰巧能对的错误
有初学者会将 AJAX 请求和 JSON 划上等号,认为从 JS 代码中向后台传送一个 JS 对象就是发出了 AJAX 请求,或者认为,发送 JS 对象是 AJAX 请求中最核心、最关键的一步。
基于上述(错误的)思路,他们会写出如下代码:
$.ajax({
url: '...',
type: "post",
data: obj,
dataType: 'json',
success: function(result) {
...
}
});
并且,由于上述代码是对的!通过上述代码,你确实是向后台发出了 AJAX 请求,因此,他们反过来越发认为自己的「思路」是完全正确的。
无论你清楚,还是不清楚:有意,还是无意,上述代码实际上省略了一些东西,在省略了这些东西的情况下,$.ajax 方法会启用默认值。
如果将上述代码省略掉的部分不全,它的完整形式如下:
$.ajax({
url: '...',
type: "post",
contentType: 'application/x-www-form-urlencoded',
data: $.param(obj),
dataType: 'json',
success: function(result) {
...
}
});
上述代码向后台发出了 AJAX 请求,请求参数是 Query String 形式,而非初学者「心里以为」的 JSON 。
引起初学者误解的原因在于 2 个参数:data 和 dataType 。
-
data 属性:
$.ajax 方法的 data 属性需要的本质上是字符串!字符串!字符串!不是对象!不是对象!不是对象!
只不过,$.ajax 方法考虑到你的懒惰,决定帮你「转换」一下:将你传入的对象转换为 Query String 格式字符串,即,$.param 方法的逻辑。
只不过,初学者压根不知道 $.ajax 帮了我们一把,更不知道 $.ajax 方法帮我们把对象转换成了啥格式。就误以为 $.ajax 能向后台传个 JS 对象。
-
dataType 属性:
dataType 属性和 data 属性长得很像,常常「被误解用于」表明 data 属性的值的类型,再加上初学者满脑子都是「通过 data 属性向后台传 JS 对象」,所以,看见 dataType 属性的值是 json 时就特别亲切。傻得可爱
dateType 是你预期的服务器返回的数据格式/类型。理论上,它应该和服务器的响应的 content-type 是一致的。在 AJAX 请求中,它通常就是
json
。为它赋值为
json
的作用是让 、$.ajax 方法「帮」我们后台响应给我们的 JSON 格式字符串转换为 JS 对象,方便你后续在 success 方法中操作。dataType 属性是和 AJAX 响应有关的属性,和请求过程无关!
另外,基于同样的思路,有人本来能「瞎猫碰死耗子」似得碰巧发出 AJAX 请求,但是基于同样的错误的思路,将 dataType 属性值赋值为 application/json,这样,就彻底不对了:$.ajax 方法总是进入 error 部分,无论如何,都不会走 success 。
3. ajax 方法的 error 参数
::: tip
提前说明,在有的 API 设计方案中,永远都不会进入 error 。所以,.ajax() 方法的 error fanction 总不会执行。
:::
当 http 响应的状态码不是 200 的时候,就会执行 error function
。
::: warning
一个常见的 Bug 是 data 属性值本应是 json
,但是不小心错写成 applicaiton/json
。初学者大多都会误用 data 属性。
这种情况下,ajax 方法总是会进入 error 部分。因为你的预期的返回的数据类型(application/json
)与实际类型(json
)并不一致,也算是 error 。
:::
一般 error 函数返回的参数有三个:function(XMLHttpRequest, textStatus, errorThrown)
。我们关注的是第一个 XMLHttpRequest
。
从第一个参数 XMLHttpRequest
中我们可以获得服务端返回的错误相关的信息:
-
XMLHttpRequest.status
返回的 HTTP 状态码,例如
404
、500
等错误代码。 -
XMLHttpRequest.statusText
对应状态码的错误信息。比如
404
错误信息是not found
;500
是Internal Server Error
。 -
XMLHttpRequest.responseText
服务器响应返回的文本信息,即,Response 的 body 的内容。