AJAX
- 在浏览器端进行网络编程(发送请求、接收响应)的技术方案
- 以通过 JavaScript 直接获取服务端最新的内容而不必重新加载页面
- 自动更新页面内容,提升用户体验,无刷新的体验
发送 ajax 请求步骤
1、创建 XMLHttpRequest 类型的对象
2、准备发送,打开与一个网址之间的连接
3、执行发送动作
4、指定 xhr 状态变化事件处理函数
// 1.创建一个 XMLHttpRequest 类型的对象 --- 相当于打开了一个浏览器
var xhr = new XMLHttpRequest();
// 2.打开一个与网址之间的连接 --- 相当于在地址栏输入网址
xhr.open("GET","https://jsonplaceholder.typicode.com/users");
// 3.通过连接发送一次请求 --- 相当于点击回车或者超链接
xhr.send(null);
// 4.指定 xhr 状态变化事件处理函数 --- 相当于处理网页呈现后的操作
xhr.onreadystatechange = function () {
// 通过判断 xhr 的 readyState ,确定此次请求是否完成
if (this.readyState === 4) {
console.log(this.responseText); //打印返回的所有数据
}
}
原生 AJAX 详解
// 1.创建一个 XMLHttpRequest 类型的对象
var xhr = null;
// 兼容写法
if (window.XMLHttpRequest) {
// 标准浏览器
xhr = new XMLHttpRequest();
} else {
// IE 6 浏览器
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
// 2.open() 方法开启请求
// xhr.open("GET","https://jsonplaceholder.typicode.com/users?id=1");
xhr.open("POST","https://jsonplaceholder.typicode.com/users");
// 设置请求头
// 一般 get 方法不需要设置,而 post 方法必须设置
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
// 3.send() 方法发送一次请求
// 如果是 get 方法请求,不需要再 send 中传参数,它如果想传参数,直接写在网址上
// xhr.send(null);
xhr.send("name=harry&age=19");
xhr.onreadystatechange = function () {
// 通过判断 xhr 的 readyState ,确定此次请求是否完成
if (this.readyState === 4) {
console.log(this.responseText)
}
}
XMLHttpRequest 类型对象
AJAX API 中核心提供的是一个 XMLHttpRequest 类型,所有的 AJAX 操作都需要使用到这个类型。
var xhr = new XMLHttpRequest();
xhr = new ActiveXObject("Microsoft.XMLHTTP") // IE6 兼容open() 方法开启请求
• 本质上 XMLHttpRequest 就是 JavaScript 在 Web 平台中发送 HTTP 请求的手段,所以我们发送出去的请求仍然是 HTTP 请求,同样符合 HTTP 约定的格式。
• 语法:xhr.open(method, url)
• method:要使用的HTTP方法,比如「GET」、「POST」、「PUT」、「DELETE」等。
• url:要向其发送请求的 URL 地址,字符串格式。setRequestHeader() 方法设置请求头
• 此方法必须在 open() 方法和 send() 之间调用。
• 语法:xhr.setRequestHeader(header, value);
• header: 一般设置 “Content-Type”,传输数据类型,即服务器需要我们传送的数据类型
• value: 具体的数据类型,常用 "application/x-www-form-urlencoded" 和
"application/json"。send() 方法发送请求
• 用于发送 HTTP 请求
• 语法:xhr.send(body)
• body:在XHR请求中要发送的数据体,根据请求头中的类型进行传参。
• 如果是 GET 方法,无需设置数据体,可以传 null 或者不传参。-
readyState 属性(根据readyState响应状态)
• readyState 属性返回一个 XMLHttpRequest 代理当前所处的状态,由于readystatechange 事件是在 xhr 对象状态变化时触发(不单是在得到响应时),也就意味着这个事件会被触发多次,所以我们有必要了解每一个状态值代表的含义:
// 1.创建一个 XMLHttpRequest 类型的对象
var xhr = null;
// 兼容写法
if (window.XMLHttpRequest) {
// 标准浏览器
xhr = new XMLHttpRequest();
} else {
// IE 6 浏览器
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
console.log("UNSENT",xhr.readyState);
// 2.open() 方法开启请求
xhr.open("GET","https://jsonplaceholder.typicode.com/users");
console.log("OPENED",xhr.readyState);
// 3.send() 方法发送一次请求
xhr.send("name=harry&age=19");
// 4.指定回调函数,处理得到的数据
xhr.onreadystatechange = function () {
// 通过判断 xhr 的 readyState ,确定此次请求是否完成
if (this.readyState === 2) {
console.log("headers received",xhr.readyState);
} else if (this.readyState === 3) {
console.log("loading",xhr.readyState)
console.log(xhr.responseText)
} else if (this.readyState === 4) {
console.log("done",xhr.readyState)
console.log(xhr.responseText)
}
}
- 事件处理函数
xhr.onreadystatechange = function() {
if (this.readyState === 4) {
// 后续逻辑......
}
};
同步与异步
// 1.创建一个 XMLHttpRequest 类型的对象
var xhr = null;
// 兼容写法
if (window.XMLHttpRequest) {
// 标准浏览器
xhr = new XMLHttpRequest();
} else {
// IE 6 浏览器
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
// 2.打开一个与网址之间的连接
// 设置同步或异步
xhr.open("GET","https://jsonplaceholder.typicode.com/users",true); // true表示异步
// xhr.open("GET","https://jsonplaceholder.typicode.com/users",false);
// 如果设置了同步加载,程序会卡在 send 部分
xhr.onreadystatechange = function () {
// 通过判断 xhr 的 readyState ,确定此次请求是否完成
if (this.readyState === 4) {
console.log("请求成功")
}
}
// 3.通过连接发送一次请求
xhr.send(null);
// 4.指定 xhr 状态变化事件处理函数
// Ajax 后面的代码
console.log("After Ajax");
Ajax 中的实现
• xhr.open() 方法第三个参数要求传入的是一个 boolean 值,其作用就是设置此次请求是否采用异步方式执行
• 默认为 true 异步,如果需要同步执行可以通过传递 false 实现
• 如果采用同步方式执行,则代码会卡死在 xhr.send() 这一步建议
• 为了让这个事件可以更加可靠(一定触发),在发送请求 send() 之前,一定是先注册readystatechange
• 不论是同步或异步都能触发成功
• 了解同步模式即可,切记不要使用同步模式
响应数据格式
- json类型数据格式
• 服务端应该根据响应内容的格式设置一个合理的 Content-Type。
var str = '{"name": "tom","age": 80}';
// 使用 JSON 对象的 parse 方法可以将 json 格式的字符串转换成 对象格式,
// 具有了属性和方法,方便我们在js 中进行使用
console.log(JSON.parse(str));
var strObj = JSON.parse(str);
console.log(strObj.name)
console.log(strObj.age)
// js 对象字面量
var obj = {
name: "tom",
age: 19,
cp: {
name: "harry",
age: 18
}
};
// 把js对象转换为字符串类型
console.log(JSON.stringify(obj));
- JSON Server
• json-server 是一个 Node 模块,运行 Express 服务器,你可以指定一个 json 文件作为api 的数据源。
• 也就是说,我们可以使用它快速的搭建一个 web 服务器。
• 网址:https://github.com/typicode/json-server
原生 AJAX 具体用法
- GET 请求
• 通常在一次 GET 请求过程中,参数传递都是通过 URL 地址中的?
参数传递。
• 一般在 GET 请求中,无需设置请求头
• 无需设置响应体,可以传 null 或者干脆不传
var xhr = new XMLHttpRequest();
// 发送 GET 请求
xhr.open("GET", "http://localhost:3000/users?age=19");
xhr.send(null);
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
}
- POST 请求
• POST 请求过程中,都是采用请求体承载需要提交的数据。
• 需要设置请求头中的 Content-Type,以便于服务端接收数据
• 需要提交到服务端的数据可以通过 send 方法的参数传递
var xhr = new XMLHttpRequest();
// post 请求
xhr.open("POST","http://localhost:3000/users");
// 设置请求头
// xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.setRequestHeader("Content-Type","application/json");
// xhr.send("name=lily&age=19&class=2");
// xhr.send(`{
// "name": "lulu",
// "age": 18,
// "class": 2
// }`);
xhr.send(JSON.stringify({
"name": "harry",
"age": 18,
"class": 1
}));
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
}
处理响应数据渲染
- 可以使用模版引擎或者 ES6 提供的模板字符串
// 获取元素
var box = document.getElementById("box");
var xhr = new XMLHttpRequest();
// 发送 GET 请求
xhr.open("GET", "http://localhost:3000/users");
xhr.send(null);
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
// 讲获取的响应体的字符串转为对象
var data = JSON.parse(this.responseText)
console.log(data);
var str = "";
// 循环遍历数组
for (var i = 0 ; i < data.length ;i++) {
// 进行字符串拼接
// str += "" + data[i].id + " " + data[i].name + " " + data[i].age + " " + data[i].class + " ";
// 使用 模板字符串 进行拼接
str += `
${data[i].id}
${data[i].name}
${data[i].age}
${data[i].class}
`
}
box.innerHTML += str;
}
};
封装 AJAX 库
// 封装自己的 Ajax 函数
/**
* 参数1:{string} method 请求方法
* 参数2:{string} url 请求地址
* 参数3:{Object} params 请求参数
* 参数4:{function} done 请求完成后执行的回调函数
/
function ajax(method, url, params, done) {
// 统一将方法中的字母转大写,便于后面判断
method = method.toUpperCase();
// 书写 IE 6 的兼容
var xhr = window.XMLHttpRequest
? new XMLHttpRequest()
: new ActiveXObject("Microsoft.XMLHTTP");
// 将对象格式的参数转为 urlencoded的格式
var pairs = [];
for (var k in params) {
pairs.push(k + "=" + params[k]);
}
var str = pairs.join("&");
// 判断是否是 get 方法,需要更改 url 的值
if (method === "GET") {
url += "?" + str;
}
// 创建打开一个连接
xhr.open(method, url);
var data = null;
// 如果是 post 方法,需要设置请求头,还有请求体
if (method === "POST") {
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
data = str;
}
xhr.send(data);
// 执行回调函数
xhr.onreadystatechange = function () {
if (this.readyState !== 4) return;
// 执行外部传进来的回调函数即可
// 需要用到响应体
done(JSON.parse(this.responseText));
}
}
// 本地存在dbs.json文件
// 调用函数
ajax("GET", "http://localhost:3000/users",{"id": 1},function (data) {
console.log(data);
});
ajax("POST", "http://localhost:3000/users",{"name": "john","age": 19,"class": 2},function (data) {
console.log(data);
});
jQuery 中的 AJAX
$.ajax()常用选项参数介绍:
• url:请求地址
• type:请求方法,默认为get
• dataType:服务端响应数据类型
• contentType:请求体内容类型,默认application/x-www-form-urlencoded
• data:需要传递到服务端的数据,如果 GET 则通过 URL 传递,如果 POST 则通过请求体传递
• timeout:请求超时时间
• beforeSend:请求发起之前触发
• success:请求成功之后触发(响应状态码 200)
• error:请求失败触发
• complete:请求完成触发(不管成功与否)GET 请求
• GET 请求快捷方法:$.get(url, data, callback)
// 化简后的方法直接发送 get 请求
$.get("http://localhost:3000/comments", {"id": 1}, function (data) {
console.log(data);
})
- POST 请求
• POST 请求快捷方法:$.post(url, data, callback)
// $.post() 快捷方法发送请求
$.post("http://localhost:3000/comments", {"postId": 3, "content": "bad"},function (data) {
console.log(data);
})
- put 请求,更改数据
$.ajax({
url: "http://localhost:3000/comments/4",
type: "put",
dataType: "json",
data: {"content": "good", "postId": 2},
success: function (data) {
console.log(data)
}
})
- delete 请求,删除数据
$.ajax({
url: "http://localhost:3000/comments/5",
type: "delete",
success: function (data) {
console.log(data)
}
})
jQuery 中其他 Ajax 方法
- 引入Ajax库
- $.ajaxSetup()
// ajaxSetup() 方法,设置默认的参数
$.ajaxSetup({
url: "http://localhost:3000/users",
type: "post"
})
// 发送 ajax请求
$.ajax({
data: {"name": "polly", "age": 17, "class": 4}
})
$.ajax({
data: {"name": "james", "age": 18, "class": 4}
})
Axios--AJAX 封装库
// 体会 get 请求
axios.get("http://localhost:3000/posts")
.then(function (response) {
console.log(response.data)
})
.catch(function (error) {
console.log(error)
})
- Axios API
• 可以通过向 axios() 传递相关配置来创建请求
• axios(config) config为对象格式的配置选项
• axios(url, config) config 可选
// axios 方法
axios({
url: "/comments",
method: "post",
baseURL: "http://localhost:3000",
headers: {
"Content-Type": "application/json"
},
timeout: 1000,
data: {
"postId": 3,
"content": "better"
}
}).then(function (res) {
console.log(res.data)
}).catch(function (error) {
console.log(error)
})
Axios常用配置项
• url 用于请求的服务器 URL,必需
• method 创建请求时使用的方法
• baseURL 传递相对 URL 前缀,将自动加在 url 前面
• headers 即将被发送的自定义请求头
• params 即将与请求一起发送的 URL 参数
• data 作为请求主体被发送的数据
• timeout 指定请求超时的毫秒数(0 表示无超时时间)
• responseType 表示服务器响应的数据类型,默认 “json”then 和 catch
axios()
.then(function (response) {
// 正常请求的响应信息对象 response
})
.catch(function (error) {
//捕获错误
})
- 全局配置默认值
• 可以指定将被用在各个请求的配置默认值
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
// 全局配置默认值
axios.defaults.baseURL = "http://localhost:3000";
// axios 方法
axios({
url: "/comments",
method: "get"
}).then(function (res) {
console.log(res.data)
}).catch(function (error) {
console.log(error)
})
- axios 简写方法
axios("http://localhost:3000/posts", {
params: {
id: 1
}
})
.then(function (res) {
console.log(res.data)
})
.catch(function (error) {
console.log(error)
})
- 拦截器
• 在请求或响应被 then 或 catch 处理前拦截它们。
// 使用拦截器,对请求进行拦截处理
axios.interceptors.request.use(function (config) {
config.params = {
id: 2
}
config.baseURL = "http://localhost:3000"
return config
})
// 对响应进行拦截
axios.interceptors.response.use(function (response) {
return response.data;
})
// axios 方法
axios("/posts")
.then(function (res) {
console.log(res)
})
.catch(function (error) {
console.log(error)
});
axios("/comments")
.then(function (res) {
console.log(res)
})
.catch(function (error) {
console.log(error)
})
- 快速请求方法
• axios.get(url[, config])
• axios.post(url[, data[, config]])
• axios.delete(url[, config])
• axios.put(url[, data[, config]])
// get 请求
axios.get("http://localhost:3000/users?id=2")
.then(function (res) {
console.log(res.data)
})
axios.get("http://localhost:3000/users",{
params: {
id: 3
}
})
.then(function (res) {
console.log(res.data)
})
// post 请求 ,添加数据
axios.post("http://localhost:3000/users",{
"name": "nancy",
"age": 19,
"class": 2
})
.then(function (res) {
console.log(res.data)
})
XMLHttpReque
• xhr.onload 事件:只在请求完成时触发
• xhr.onprogress 事件:只在请求进行中触发
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:3000/posts");
xhr.onload = function () {
console.log("load",this.readyState)
}
xhr.onprogress = function (e) {
console.log("progress",this.readyState)
// 在周期性请求过程中,接收到的数据的个数
console.log(e.loaded);
// 接收数据的总个数
console.log(e.total);
}
xhr.send(null);