ajax

Ajax 全称是 asynchronous javascript and xml,并不是新的编程语言,可以说是已有技术的组合,主要用来实现客户端与服务器端的异步通信效果,实现页面的局部刷新,从而创建快速动态网页的技术。

Ajax 过程

  • 创建 XMLHttpRequest 对象,也就是创建一个异步调用对象
  • 创建一个新的 HTTP 请求,并指定其请求的方法、URL 及验证信息
  • 设置响应 HTTP 请求状态变化的函数
  • 发送 HTTP 请求
  • 获取异步调用返回的数据
  • 使用 JavaScript 和 DOM 实现局部刷新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var xhr = null; // 创建异步对象
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest(); // ie7+等现代浏览器
} else if (window.ActiveXObject) {
// ie6,老版Opera
xhr = new ActiveXObject("Microsft.XMLHTTP");
}
xhr.open("get", "http://localhost:4000/test", true); // true是异步,可省略
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); // post 必须设置
xhr.onreadystatechange = function () {
// 若为同步,此代码不用写,直接在send后,用`xhr.responseText`即可。
if (xhr.readyState == 4 && xhr.status == 200) {
/*
readyState
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪
status
200 OK
404 Not Found
*/
xhr.responseText;
xhr.responseXML.children[0].children;
JSON.parse(xhr.responseText);
}
};
xhr.send(String); // 用于post传参,形式:"a=1&b=2",而get传参就在url后面用“?”拼接

优缺点
优点:可以使得页面不重载全部内容的情况下加载局部内容,降低数据传输量,避免用户不断刷新或者跳转页面,提高用户体验
缺点:对搜索引擎不友好,要实现 ajax 下的前进后退功能成本较大;跨域问题限制

jQuery 中的 Ajax

全局 ajax 事件处理器
jQuery 库支持完整的 Ajax 操作。这里所包含的所有函数和方法用于从服务端加载数据,并且$\color{red}{不会导致页面刷新}$。

$(document).ajaxComplete(handler(event, XMLHttpRequest, ajaxOptions))

当 Ajax 请求完成后注册一个回调函数。
每当一个 Ajax 请求完成,jQuery 就会触发 ajaxComplete 事件,在这个时间点所有处理函数会使用.ajaxComplete()方法注册并执行。
从 jQuery 1.8 开始, .ajaxComplete() 方法只能绑定到 document 元素。
如果 global 选项设置为 false,调用$.ajax() 或 $.ajaxSetup(),.ajaxComplete()方法将不会被触发。
类似的还有:请求出错 ajaxError()、请求发送前 ajaxSend()、请求刚开始 ajaxStart()、请求完成时 ajaxStop()、请求成功完成时 ajaxSuccess()

辅助函数

$.param() 创建一个数组或对象序列化的字符串,适用于一个 URL 地址查询字符串或 Ajax 请求。此方法无法对复杂数据结构进行编码。

serialize() 将用作提交的表单元素的值编译成字符串。

1
2
3
4
5
6
7
8
9
10
11
<form action="#">
<input name="username" value="abc" />
<input name="age" value="24" />
<select name="sex">
<option value="0"></option>
<option value="1"></option>
</select>
<input type="submit" value="提交" />
</form>

console.log($("form").serialize()); // username=abc&age=24&sex=0

serializeArray() 将用作提交的表单元素的值编译成拥有 name 和 value 对象组成的数组。

1
console.log($("form").serializeArray()); // [{name: "username", value: "abc"}, {name: "age", value: "24"}, {name: "sex", value: "0"}]

底层接口

$.ajax(url, {})或$.ajax({url: “”})

关于传参项(可以使用$.ajaxSetup()设置任何默认参数),下面列举一些常用的:

  • url:String,一个用来包含发送请求的 URL 字符串
  • data:Object、String,发送到服务器的数据。将自动转换为请求字符串格式。GET 请求中将附加在 URL 后面。
  • dataType:String,默认 Intelligent Guess (xml, json, script, or html))。预期服务器返回的数据类型。
        xml,html,script,json,text
        jsonp: 以 JSONP 的方式载入 JSON 数据块。会自动在所请求的 URL 最后添加 “?callback=?”。默认情况下不会通过在 URL 中附加查询字符串变量 “_=[TIMESTAMP]” 进行自动缓存结果,除非将 cache 参数设置为 true。
  • accepts:PlainObject(可用$.isPlainObject()检测),内容类型发送请求头(Content-Type),用于通知服务器该请求需要接收何种类型的返回结果。如果 accepts 设置需要修改,推荐在$.ajaxSetup() 方法中设置一次。
  • async:Boolean,默认 true,异步请求
  • global:Boolean,默认 true。该请求是否触发全局处理事件(如$(document).ajaxComplete()等)
  • beforeSend(jqXHR, settings):Function,请求发送前的回调函数,用来修改请求发送前 jqXHR,此功能可用来设置自定义 HTTP 头信息,在 beforeSend 函数中返回 false 将取消这个请求。
  • catch:Boolean,默认 true,dataType 为”script”和”jsonp”时默认为 false。是否缓存此页面,原理是在 GET 请求参数中附加”_=时间戳”。该参数不是其他请求所必须的,除了在 IE8 中,当一个 POST 请求一个已经用 GET 请求过的 URL。
  • complete:Function,请求完成后回调函数 (请求 success 和 error 之后均调用)。
  • success(data, textStatus, jqXHR):Function,请求成功时调用函数
  • error:Function,请求失败时调用函数
  • timeout:Number,设置请求超时时间(毫秒)。此设置将覆盖$.ajaxSetup() 里的全局设置。
  • jsonp:String,在一个 jsonp 请求中重写回调函数的名字。这个值用来替代在”callback=?”这种 GET 或 POST 请求中 URL 参数里的”callback”部分,比如{jsonp:’onJsonPLoad’}会导致将”onJsonPLoad=?”传给服务器。在 jQuery 1.5,,设置 jsonp 选项为 false,阻止了 jQuery 从加入”?callback”字符串的 URL 或试图使用”=?”转换。在这种情况下,你也应该明确设置 jsonpCallback 设置。例如, { jsonp: false, jsonpCallback: “callbackName” }
  • jsonpCallback:String、Function,为 jsonp 请求指定一个回调函数名。这个值将用来取代 jQuery 自动生成的随机函数名。这主要用来让 jQuery 生成一个独特的函数名,这样管理请求更容易,也能方便地提供回调函数和错误处理。你也可以在想让浏览器缓存 GET 请求的时候,指定这个回调函数名。从 jQuery 1.5 开始,你也可以使用一个函数作为该参数设置,在这种情况下,该函数的返回值就是 jsonpCallback 的结果。
  • contents: PlainObject,一个以”{字符串/正则表达式}”配对的对象,根据给定的内容类型,解析请求的返回结果。
  • contentType:String,默认 application/x-www-form-urlencoded; charset=UTF-8。发送信息至服务器时内容编码类型。
  • context:Object,设置 Ajax 相关回调函数的上下文。即改变回调函数的 this,默认就是传入的整个对象。
  • converters: PlainObject,默认: {“* text”: window.String, “text html”: true, “text json”: jQuery.parseJSON, “text xml”: jQuery.parseXML}。一个数据类型到数据类型转换器的对象。每个转换器的值是一个函数,返回经转换后的请求结果。
  • crossDomain:Boolean,同域请求为 false, 跨域请求为 true。如果你想在同一域中强制跨域请求(如 JSONP 形式),例如,想服务器端重定向到另一个域,那么需要将 crossDomain 设置为 true 。
  • username:String,于响应 HTTP 访问认证请求的用户名
  • password:String,用于响应 HTTP 访问认证请求的密码

$.ajax() 返回 jqXHR 对象,可调用

  • .done() success
  • .fail() error
  • .always() complete
  • .then() 传两个回调函数,分别是 done 和 fail

$.ajaxPrefilter([dataTypes], handler(options, originalOptions, jqXHR) )

在每个请求之前被发送和$.ajax()处理它们前处理,设置自定义 Ajax 选项或修改现有选项。

$.ajaxSetup(options) 为以后要用到的 Ajax 请求设置默认的值,其后的 AJAX 请求不再设置任何已设置的选项参数。

快捷方法

  • $.get() {type: “get”}
  • $.post() {type: “post”}
  • $.getScript() {type: “script”}
  • $.getJSON() {type: “json”}
  • $(selector).load() 从服务器载入数据并且将返回的 HTML 代码并插入至 匹配的元素中。

Axios

  • axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

在 react 项目中使用 axios 的 Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
// data.js
const data = {};

export default function () {
const args = arguments;
const len = args.length;
if (len > 1) {
return (data[args[0]] = args[1]);
}
if (len === 1) {
return data[args[0]];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// request
import React from "react";
import axios from "axios";
import { Modal } from "antd";
import gdata from "../root/data";

/**
* @func 请求配置
* @author 大宝
*/

const request = axios.create({
baseURL: "/api/fuwu/web/",
});
// 拦截器
request.interceptors.response.use(
(response) => {
const data = response.data || {};
const { url } = response.config;
if (response.status == 200) {
if (data.result == "losesession") {
window.location.href = `${gdata(
"ucDomain"
)}/Contents/usercenter/allow/login/login.jsp?redirecturl=jss&jumpurl=${encodeURIComponent(
window.location.href
)}`;
return Promise.reject();
}
}
},
(error) => Promise.reject(error)
);
export default request;

如果接口返回的字段等于 losesession 要求用户重新去登录页面去登录。

Ajax、jQuery.ajax、Axios 和 Fetch 的区别

  • ajax 最早出现的发送后端请求技术,利用用 XMLHttpRequest 对象。
  • $.ajax 是 jQuery 中的发送后端请求技术,基于原生 Ajax 的封装。
  • Axios 不是原生 JS 的,需要进行安装。它在 client-side 和 server-side 都可以使用。也可以在请求和响应阶段进行拦截。它是基于 promise 对象的。
  • Fetch 号称是 AJAX 的替代品,使用了 ES6 中的 promise 对象。其参数有点像 jQuery.ajax。但是 fetch 不是对 ajax 的封装,而是原生 js 实现的,并没有使用 XMLHttpRequest 对象。