1w/.#### 1. 如何发送一个ajax请求?
- 创建ajax对象
语法:var xhr = new XMLHttpRequest();
xhr就是我们需要的ajax对象,能帮我们发送一个请求 - 配置本次请求的信息
语法:xhr.open(“请求方式”,“请求地址”,是否异步);
请求地址:基准地址+接口地址
默认为异步的,选填 - 把配置好的请求发送出去
语法: xhr.send(); - 配置一个请求完成的事件
语法: xhr.onload = function(){代码}
时机:会在当前请求完成以后被触发(后端给回对应的响应以后)
如何拿到后端给的信息(数据):在ajax对象内有一个成员叫做responseText
JSON.parse(json格式数据) JSON.parse(xhr.responseText)
2. ajax的异步请求?
- ajax是一个默认异步的技术手段
- ajax强烈不推荐同步请求
=》同步:从上到下一依次执行,上一行代码没有完成,后面的代码不会执行,当网络环境不好的时候,一旦请求发送出去,当请求没有回来的时候,什么都干不了
=》异步:先放在队列池里面,等到所有同步代码执行完毕,再执行异步的代码
ajax的异步出现在什么时候?
- 创建ajax对象 同步代码
- 配置请求信息 同步代码
- 发送本次请求 同步发送,异步接受
- 绑定事件 同步绑定事件,会根据ajax完成以后触发
结论: 如果发送异步请求,步骤可以是1,2,3,4或者1,2,4,3
如果发送同步请求,步骤必须是1,2,4,3,之后写请求写成1,2,4,3
3. 常见的请求方式(了解)
- GET:偏向获取的语义,当你需要向服务器索要一些数据的时候使用
- POST:偏向提交的语义,当你需要给服务器一些数据的时候使用
- PUT:偏向提交的语义,偏向提交给服务器,服务器进行添加操作
- DELETE:偏向删除的语义,告诉服务器需要删除一些信息
- PATCH:偏向提交的语义,偏向提交给服务器,服务器进行局部信息的修改
- HEAD:用于获取服务器响应头信息的一个请求
- CONNECT:保留请求的方式
- OPTIONS:不需要任何响应的请求,只是为了获取服务器信息,需要服务器运行
GET和POST的区别(掌握)?
1. 语义不一样
GET偏向获取,POST偏向提交
2. 携带信息的位置不一样
GET:直接在请求地址后面以查询字符串的形式进行拼接
POST:是在请求体内进行信息的携带
3. 携带信息的大小不一样
GET:原则上可以携带任意大小的数据,但会被浏览器限制(IE:2KB)
POST:原则上可以携带任意大小的数据,但是会被服务器限制
4. 携带信息的格式不一样
GET: 只能携带查询字符串格式
POST:可以携带很多格式(查询字符串/json/二进制流/…),但是需要在发送请求的时候特殊说明一下
5. 安全问题
GET: 明文发送,相对不安全
POST:暗文发送,相对安全
GET 查询字符串:‘key=value&key2=value2’
注意:地址和查询字符串之间使用问号分割
发送一个带有参数的POST请求
- 因为POST请求实在请求体内携带信息
- xhr.send()的小括号内,就是书写请求体的位置
- 注意:如果发送POST请求,并且需要携带信息,那么一定要在发送之前特殊说明
=》如果发送的是查询字符串:appication/x-www-form-urlencoded
=》如果发送的是json格式:application/json
=》如果发送的是二进制流:mutilpart/data - 设置特殊说明的语法
=》xhr.setRequestHeader(“content-type”,对应的类型)
const xhr = new XMLHttpRequest();
xhr.open("POST","http://localhost:8000/test/one");
xhr.onload=function(){
const res = JSON.parse(xhr.responseText);
console.log(res);
}
xhr.setRequestHeader("content-type",application/x-www-form-urlencoded)
xhr.send("name=zhangsan&age=18");
3. ajax状态码
ajax状态码:用一个数字来描述当前这个ajax处于什么步骤
语法:状态码:ajax对象.readyState
意义:0: 表示创建ajax对象成功
1: 表示配置请求信息成功
2:表示请求已经发送出去,并且服务器给回的响应已经到了浏览器
3:表示浏览器正在解析响应报文,并且把真实响应体内容逐步赋值给xhr的responseText
4:表示浏览器解析响应报文完成,对象内已经有完整的响应体内容了
事件**:xhr.onreadystatechange = function(){}**,当ajax状态码改变的时候触发
4. http状态码
- 100~199 =》表示连接继续
- 200~299 =》表示各种意义的成功
200 标准成功
201创建成功
204删除成功 - 300~399 =》表示重定向
=》重定向:你请求的是a服务器地址,但是a服务器把你的请求转嫁给了b服务器,真实给你返回数据的是b服务器
=》301:临时重定向
=》302:永久重定向
=》304:缓存 - 400~499 =》表示各种客户端错误
404:地址不对
403:权限不够 - 500~599 =》表示各种服务器错误
=》500:标准服务器错误
=》501:服务器过载或维护
语法:xhr.status
得到:本次请求的http状态码
ajax的兼容问题(了解,不主动兼容)
- 创建ajax对象的兼容问题
=》标准浏览器:new XMLHttpRequest()
=》IE低版本:new ActiveXObject(“Microsoft.XMLHTTP”);
注意:需要在正式的IE低版本内核中才能使用 - 接收响应的事件
=》标准浏览器:xhr.onload = function(){}
=》IE低版本:xhr.onreadystatechange = function(){}
->在时间内进行一些条件判断来实现
xhr.onreadystatechange = function(){
// 保证readyState === 4
// 保证 status是200-299
// 才能正常拿到所有响应体
if(xhr.readyState === 4 && /^2\d{2}$/.test(xhr.status)){
console.log(xhr.responseText);
}
}
封装Ajax
/*
参数:
1. 请求地址(url)无默认值,必填
2. 请求参数(method) 有默认值,GET
3. 是否异步(async) 默认值为true
4. 携带给后端的参数(data) 可有有,默认值为''
5. 是否存在token(token) 可以有,默认值为''
6. 是否对响应体进行解析(dataType) 可以有,'string'表示不执行JSON.parse() 选填'json'表示执行JSON.parse()
7. 请求成功后执行的函数(success) 可以有,默认是空函数 可以不传递,传递了必须是一个function类型
8. 请求失败后执行的函数(error) 可以不传递,只要床底了,必须是一个function类型
方案 以对象的方式传递参数,options就是你传递进来的所有对于本次的请求
function ajax(options={}){}
ajax({url:'xxx',token:'abcdd'})
=
*/
function ajax(options = {}) {
// 参数验证 1-1验证options.url
if (!options.url) {
// 手动抛出异常 语法:throw new Error(‘报错信息’)
// 作用:直接在控制台报错,阻断程序的继续运行
throw new Error('url为必选项')
}
// 1-2 验证options.method 可以是undefined post get
if (!(options.method === undefined || /^(get | post)$/i.test(options.method))) {
throw new Error('目前版本只接受GET和POST请求');
}
// 1-3 验证options.async 可以是undefined true false
if (!(options.async === undefined || typeof options.async === 'boolean')) {
throw new Error('async只能传递布尔值,请检查后操作');
}
// 1-4 验证options.data
if (!(options.data === undefined || typeof options.data === 'string')) {
throw new Error('data需要传递一个字符串格式')
}
// 1-5 验证options.token
if (!(options.token === undefined || typeof options.token === 'string')) {
throw new Error('token需要传递一个字符串格式')
}
// 1-6验证options.dataType
if (!(options.dataType === undefined || /^(string|json)$)/i.test(options.dataType))) {
throw new Error('dataType只能传递“string”或者“json”');
}
// 1-7 验证options.success
if (!(options.success === undefined || typeof options.success === 'funciton')) {
throw new Error('success需要传递一个function类型的数据')
}
// 1-8 验证options.error
if (!(options.error === undefined || typeof options.error === 'funciton')) {
throw new Error('error需要传递一个function类型的数据')
}
// 设置一套默认值
const _default = {
url: options.url,
method: options.method || 'GET',
// async: options.async === undefined ? true:options.async,
async: options.async ?? true, // 只有??前面为空的时候才走后面的运算,否则不走
data: options.data || '',
token: options.token || '',
dataType: options.dataType || 'string',
success: options.success || function () { },
error: options.error || function () { }
}
// 如果是get请求,并且data有内容,直接把data拼接到url的后面
if (_default.method.toUpperCase() === 'GET' && data) {
_default.url += '?' + _default.data
}
const xhr = new XMLHttpRequest();
xhr.open(_default.method, _default.url, _default.async);
xhr.onload = function () {
const result = _default.dataType.toUpperCase() === 'JSON' ? JSON.parse(xhr.responseText) : xhr.responseText;
// 判断一些请求的http状态码,200-299
if (xhr.status >= 200 && xhr.status <= 299) {
_default.success(result);
}else{
_default.error('请求失败了,地址有问题,请检查');
}
}
if (_default.token) xhr.setRequestHeader('authorization', _default.token);
if (_default.method.toUpperCase() === 'POST') xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
_default.method.toUpperCase() === 'POST' ? xhr.send(_default.data) : xhr.send();
}