什么是Ajax
- AJAX (Asynchronous JavaScript And XML(异步的 JavaScript 和 XML)
- AJAX 不是一种新的语言,而是使用 JavaScript 和 XML ( JSON ) 实现的一种新的技术
想要使用ajax向服务端请求数据,一定要开启服务器!!!
-
语法:
const xhr =new XMLHttpRequest()
创建一个ajax对象xhr.open('请求方式', '请求地址',true)
默认为true,表示异步任务,可以不传xhr.send()
发送请求xhr.onload = function () {console.log(xhr.responseText)}
监听请求完成时间- 设置请求头
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')
xhr.setRequestHeader('content-type','application/JSON')
xhr.setRequestHeader('authorization','后端提供给前端的登录凭证')
-
同步异步
- ajax有两种执行方式,一般情况下都使用异步方式
- 使用同步时,不能先发送请求然后监听,要书写相反的顺序
-
http协议
当前协议规定 请求 只能是 前端发起的, 并且在传输过程中, 只能传递字符串
- 建立连接:浏览器和服务器建立连接
- 发送请求:如果需要携带一些参数, 那么需要以请求报文的形式传递,报文由浏览器进行组装, 我们只需要传递一些对应的信息
- 接收响应:报文由浏览器进行组装, 我们只需要传递一些对应的信息
- 关闭连接:浏览器和服务器的连接到此结束
我们的每一个请求都是完全独立的, 前一个请求和后一个请求没有任何关联
-
http请求状态码:(重要)
- 100~199: 连接正在进行中(持续进行)
- 200~299: 表明连接成功
- 300~399: 表明重定向
- 400~499: 表明前端错误 (没权限/传参错误)
- 500~599: 表明后端错误
-
ajax状态码
-
0(未初始化):
- (XMLHttpRequest)对象已经创建,但还没有调用open()方法。值为0表示对象已经存在,否则浏览器会报错:对象不存在。
-
1(载入/正在发送请求):
- 对XMLHttpRequest对象进行初始化,即调用open()方法,根据参数(method,url,true),完成对象状态的设置。并调用send()方法开始向服务端发送请求。值为1表示正在向服务端发送请求。
-
2(载入完成/数据接收):
- 此阶段接收服务器端的响应数据。但获得的还只是服务端响应的原始数据,并不能直接在客户端使用。值为2表示send()方法执行完成,已经接收完全部响应数据。并为下一阶段对数据解析作好准备。
-
3(交互/解析数据)正在解析响应内容:
- 此阶段解析接收到的服务器端响应数据。即根据服务器端响应头部返回的MIME类型把数据转换成能通过responseBody、responseText或responseXML属性存取的格式,为在客户端调用作好准备。值为3表示正在解析数据。
-
4 (后台处理完成)响应内容解析完成,可以在客户端调用了:
- 此阶段确认全部数据都已经解析为客户端可用的格式,解析已经完成。值为4表示数据解析完毕,可以通过XMLHttpRequest对象的相应属性取得数据。
请求方式
- 含义不同
- get: 表示获取
- post:表示提交
- 传参差异
- 传参方式
- get:直接拼接在地址的后面就行,格式类似于以前的字符串查询
- post:在请求体内书写xx.send('在这书写参数')
- 传参大小
- get:2kb左右
- post:原则上没有限制,我们可以在后端添加限制
- 传参安全
- get:明文传输,相对不安全
- post:密文传输。相对安全
- 传参格式
- get:传递的是查询字符串格式
- post:原则上没有限制,但是需要通过content-type 指定传参的格式
- 传参方式
封装ajax函数 (需要自取)
function fn (baseurl) {
return function myAjax(options) {
// console.log(options);
// 参数判断
// 请求地址不能是undefined
if (options.url === undefined) throw new Error('请求地址不能是undefined')
// method 可以是get和post,不区分大小写
const reg = /^(get|post)$/i
if (!reg.test(options.method) && options.method !== undefined) throw new Error('请传入正确的请求方式')
// async 可以是undefined 也可以是布尔值
if (options.async !== undefined && typeof (options.async) !== 'boolean') {
throw new Error('请传入正确的任务类型')
}
// data 可以是undefined 也可以是字符串
if (
!(
options.data === undefined ||
typeof (options.data) === 'string' ||
Object.prototype.toString.call(options.data) === '[object Object]'
)
) throw new Error('data传入失败')
// 设置请求头 可以是undefined 也可以是对象
if (
!(
options.header === undefined ||
Object.prototype.toString.call(options.header) === '[object Object]'
)
) throw new Error('请求头参数传入失败')
// 判断解析参数 可以是undefined 和 字符串
if (
!(
options.dataType === undefined ||
Object.prototype.toString.call(options.dataType) === '[object String]'
)
) throw new Error('解析参数传入失败')
// 参数默认值
const _options = {
url: baseurl + options.url,
method: options.method || 'get',
async: options.async ?? true,
data: options.data || '',
header: {
'content-type': 'application/x-www-form-urlencoded',
...options.header
},
dataType: options.dataType || 'JSON'
}
// 将data转化成查询字符串
if (Object.prototype.toString.call(_options.data) === '[object Object]') {
_options.data = setObj(_options.data)
}
// console.log('传入的参数', options);
// console.log('默认的参数', _options);
// 设置请求地址
_options.url = _options.method === 'get' ? `${_options.url}?${_options.data}` : _options.url
// 封装请求函数
return new Promise(function (resolve, rejected) {
const xhr = new XMLHttpRequest()
xhr.open(_options.method, _options.url, _options.async)
/**
* 设置请求头
* 情况1:header 内有 authorization 的时候
* 情况2:请求方式 为 post
* 情况3:send()的参数
*/
// 情况 1
_options.header.authorization && xhr.setRequestHeader('authorization', _options.header.authorization)
// 情况 2
if (/^post$/i.test(_options.method) && _options.data !== '') {
xhr.setRequestHeader('content-type', _options.header['content-type'])
}
// 情况 3
/^post$/i.test(_options.method) ? xhr.send(_options.data) : xhr.send();
xhr.onload = function () {
if (_options.dataType === 'string') {
return resolve({
code: 1,
msg: '请求成功',
info: xhr.responseText
})
}
// 转换数据格式
try {
const res = JSON.parse(xhr.responseText)
return resolve({
code: 1,
msg: '请求成功',
info: res
})
} catch (error) {
return resolve({
code: 0,
msg: '请求失败',
info: error
})
}
}
})
}
}
const myAjax = new fn('http://localhost:8888')
// 将data转化成查询字符串
function setObj(obj) {
let str = ''
for (let key in obj) {
let value = obj[key]
str += `${key}=${value}&`
}
str = str.slice(0, str.length - 1)
// str = str.slice(0,-1)
return str
}