文章内容输出来源:拉勾教育大前端就业急训营2期;
免费数据接口:http://jsonplaceholder.typicode.com
1、体验Ajax
// jQuery中的Ajax方法
$.ajax({
url: 'http://jsonplaceholder.typicode.com/users',
method: 'GET',
dataType: 'json',
//传参,最终请求地址为:http://jsonplaceholder.typicode.com/users?id=1
data: {"id": 1},
success: function(data){
console.log(data);
}
})
2、原生Ajax
- 创建XMLHttpRequest类型的对象(相当于打开了浏览器)
- 准备发送,打开与网页之间的连接
- 执行发送动作
- 指定XHR状态变化事件处理函数
// 1、创建XMLHttpRequest类型的对象---相当于打开了浏览器
let xhr = new XMLHttpRequest();
// 2、准备发送,打开与网页之间的连接---相当于在网页中输入网址
xhr.open('GET', 'http://jsonplaceholder.typicode.com/users');
// 3、执行发送动作,---相当于浏览器点击回车或超链接
xhr.send();
// 4、指定xhr状态变化事件处理函数,---相当于处理网页呈现后的操作
xhr.onreadystatechange = function(){
//判断xhr的readyState,确定此次请求是否完成
if(this.readyState == 4){
console.log(this.responseText);
}
};
2.1 详解XMLHttpRequest
AJAX API 中核心提供的是一个 XMLHttpRequest 类型,所有的 AJAX 操作都需要使用到这个 类型。
let xhr = new XMLHttpRequest();
存在兼容问题,兼容IE6写法:
let xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
// IE 6 浏览器
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
2.2 open
本质上 XMLHttpRequest 就是 JavaScript 在 Web 平台中发送 HTTP 请求的手段,所以我 们发送出去的请求仍然是 HTTP 请求,同样符合 HTTP 约定的格式。
- 语法:xhr.open(method, url)
- method:要使用的HTTP方法,比如「GET」、「POST」、「PUT」、「DELETE」、等。
- url:要向其发送请求的 URL 地址,字符串格式。
2.3 send方法和请求头
2.3.1 请求头
setRequestHeader() 方法设置请求头,此方法必须在 open() 方法和 send() 之间调用。 一般情况下,get方法不需要设置请求头,但是post请求必须设置
-
语法:xhr.setRequestHeader(header, value);
-
header: 一般设置 “Content-Type ” ,传输数据类型,即服务器需要我们传送的数据类型
-
value: 具体的数据类型,常用 “application/x-www-form-urlencoded” 和 “application/json”。
// 示例 xhr.open("POST", 'http://jsonplaceholder.typicode.com/users'); xhr.setRequestHeader("Content-type", 'application/x-www-form-urlencoded'); xhr.send('name=qiuqiu&age=19');
2.3.2 send ( )
用于发送 HTTP 请求 ,如果是get请求,不需要在send中传递参数,如果要传参,直接拼接到链接中即可。
- 语法:xhr.send(body)
- body:在XHR请求中要发送的数据体,根据请求头中的类型进行传参。
- 如果是 GET 方法,无需设置数据体,可以传 null 或者不传参。
xhr.send('name=qiuqiu&age=19');
2.4 响应状态分析
readyState 属性返回一个 XMLHttpRequest 代理当前所处的状态,由于 readystatechange 事件是 在 xhr 对象状态变化时触发(不单是在得到响应时)。
readyState | 状态描述 | 说明 |
---|---|---|
0 | UNSENT | 代理 XHR 被创建,但尚未调用 open() 方法 |
1 | OPENED | open() 方法已经被调用,建立了连接。 |
2 | HEADERS_RECEIVED | send() 方法已经被调用,并且已经可以获取状态行和响应头 |
3 | LOADING | 响应体下载中, responseText 属性可能已经包含部分数据 |
4 | DONE | 响应体下载完成,可以直接使用 responseText |
//使用过程中,只需要判断状态是否等于4
xhr.onreadystatechange = function(){
//判断xhr的readyState,确定此次请求是否完成
if(this.readyState == 4){
console.log(this.responseText);
}
};
3、同步和异步
同步:一个人在同一时刻只做一件事情,即使需要耗时很久的操作,也要等待完成后再去做其他事情。串联
异步:一个人在同一时刻不只做一件事情,耗时操作无需等待,直接去做其他的事情。并联。
xhr.open() 方法第三个参数要求传入的是一个 boolean 值,默认为 true 异步,如果需要同步执行可以通过传递 false 实现 ,但是如果采用同步方式执行,如果耗时很长,则代码会卡死在 xhr.send() 这一步。
建议
- 为了让这个事件可以更加可靠(一定触发),在发送请求 send() 之前,一定是先注册 readystatechange
- 不论是同步或异步都能触发成功
- 了解同步模式即可,切记不要使用同步模式
4、JSON数据格式
JSON是一种特殊的字符串。js中提供了JSON对象,其中stringify()
方法可以将对象转化为JSON字符串,parse()
方法可以将JSON字符串转化为js对象。
注意:JSON与Ajax没有必然的联系,JSON只是一种数据协议。
let obj = {
name: "Tom",
age: 20
}
console.log(JSON.stringify(obj)); // {"name":"Tom","age":20}
let str = `{"name": "tom", "age": 20}`;
let parse = JSON.parse(str);
console.log(parse.name); // tom
5、json-server
参考:http://github.com/typicode/json-server
json-server是一个Noide模块,运行express服务器,可以指定一个json文件为api的数据源,可以使用它快速的搭建一个web服务器。
5.1 安装
npm install -g json-server
5.2 创建json文件
// db.json,自定义
{
"posts": [
{ "id": 1, "title": "json-server", "author": "typicode" }
],
"comments": [
{ "id": 1, "body": "some comment", "postId": 1 }
],
"profile": { "name": "typicode" }
}
5.3 启动
json-server --watch db.json //文件名与自己的json文件名保持一致
5.4 访问
输入链接:http://localhost:3000/posts
//结果
[
{ "id": 1, "title": "json-server", "author": "typicode" }
]
6、原生Ajax-GET方法
let xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:3000/posts?id=1");
xhr.send(null);
xhr.onreadystatechange = function(){
if(this.readyState == 4){
console.log(this.responseText)
}
}
7、原生Ajax-POST方法
需要设置请求头,便于服务器接收数据,传递的数据通过send方法的参数进行传递
7.1 application/x-www-form-urlencoded
let xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:3000/posts");
xhr.setRequestHeader("Content-type", 'application/x-www-form-urlencoded');
xhr.send("id=2&title=json&author=qiuqiu");
xhr.onreadystatechange = function(){
if(this.readyState == 4){
console.log(this.responseText)
}
}
7.2 application/json
let xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:3000/posts");
xhr.setRequestHeader("Content-type", 'application/json');
let body = {
"id": 3,
"title": "json1",
"author": "qiuqiu"
};
xhr.send(JSON.stringify(body));
xhr.onreadystatechange = function(){
if(this.readyState == 4){
console.log(this.responseText)
}
}
8、数据渲染
使用模板字符串
let box = document.getElementById("box");
let xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:3000/posts");
xhr.send(null);
xhr.onreadystatechange = function(){
if(this.readyState == 4){
//将获取的响应体转化为对象
let data = JSON.parse(this.responseText);
let str = '';
for(let i = 0; i < data.length; i++){
str += `
<tr>
<td>${data[i].id}</td>
<td>${data[i].title}</td>
<td>${data[i].author}</td>
</tr>
`;
}
box.innerHTML += str;
}
}
9、封装Ajax库
工作过程中,有别人封装好的可以直接拿来用,此处是了解封装的过程。
// ajax操作
/*
* 参数1:{string} method 请求方法
* 参数2:{string} url 请求地址
* 参数3:{object} params 请求参数
* 参数4:{function} done 请求完成后执行的函数
*/
function ajax(method, url, params, done){
//将method转大写
method = method.toUpperCase();
let xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microaoft.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;
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));
}
}
ajax("get", 'http://localhost:3000/posts', null, function(res){
console.log(res)
})