繁星永存 记忆亘古不变

推荐使用 Axios

  • Axios 是专注于网络数据请求的库。
  • 相比于原生的 XMLHttpRequest 对象,axios 简单易用
  • 相比于 jQuery,axios 更加轻量化,只专注于网络数据请求。

传统的Ajax (XHR)

基本使用步骤

  1. 创建 xhr 对象

  2. 调用 xhr.open()函数

  • (POST 请求)设置 Content-Type 属性(固定写法)
  1. 调用 xhr.send() 函数

  2. 监听 xhr.onreadystatechange 事件

GET请求

// 创建 xhr 对象
const xhr = new XMLHttpRequest()
// 调用 open 指定请求方式和 url 地址
// 带有参数可以使用查询字符串格式
// 请求地址URL用 ? 拼接
// 例如 id=1&&page=2
xhr.open('GET','https://www.baidu.com/api?id=1&&page=2')
// 调用 send 发起 Ajax 请求
xhr.send()
// 监听发起请求后的事件,onreadystatechange
xhr.onreadystatechange = function() {
// 监听
// 请求对象的请求状态 readyState
// 服务器响应状态 status
if(xhr.readyState === 4 && xhr.status === 200){
// responeseText响应回来的数据
console.log(xhr.responeseText)
}
}

POST请求

// // 创建 xhr 对象
const xhr = new XMLHttpRequest()
// 调用 open 指定请求方式和 url 地址
xhr.open('POST','https://www.baidu.com/api')
// 设置 Content-Type 属性(固定写法)
xhr.setRequestHeader('Content-Type''application/x-www-form-urlencoded')
// 调用 send(),同时将数据以查询字符串的形式,提交给服务器
xhr.send('id=1&author=fantasy&page=2)
// 监听发起请求后的事件,onreadystatechange
xhr.onreadystatechange = function() {
// 监听
// 请求对象的请求状态 readyState
// 服务器响应状态 status
if(xhr.readyState === 4 && xhr.status === 200){
// responeseText响应回来的数据
console.log(xhr.responeseText)
}
}

XMLHttpRequest 对象的 readyState 属性,用来表示当前 Ajax 请求所处的状态。每个 Ajax 请求必然处于以下状态中的一个:

状态描述
0UNSENTXMLHttpRequest 对象已被创建,但尚未调用 open方法。
1OPENEDopen() 方法已经被调用。
2HEADERS_RECEIVEDsend() 方法已经被调用,响应头也已经被接收。
3LOADING数据接收中,此时 response 属性中已经包含部分数据。
4DONEAjax 请求完成,这意味着数据传输已经彻底完成或失败。

设置 HTTP 请求时限

xhr.timeout = 3000
xhr.ontimeout = function(event){
alert('请求超时!')
}

设置 http 请求时限,3000毫秒,超时执行 ontimeout 的回调函数

FormDate 对象管理表单数据

基本使用

// 新建 FormData 对象
const fd = new FormDate()
// 添加数据 加入表单项
fd.append('id','12')
fd.append('name','fantasy')

// post 请求直接发送 FormData对象
// ...Ajax请求代码
xhr.send(fd)

获取网页 dom 表单的值

// 获取 dom 表单
const form = document.querySelector('#form')
// 监听表单提交
form.addEventListener('submit'function(e) {
// 阻止表单默认行为
e.preventDefault()
//根据 form 表单创建 FormData 对象,会自动将表单数据填充到 FormData 对象中
const fd = new FormData(form)
// post 请求直接发送 FormData对象
// ...Ajax请求代码
xhr.send(fd)
}

上传文件

// 1. 创建 FormData 对象
var fd = new FormData()
// 2. 向 FormData 中追加文件
fd.append('avatar', files[0])
// post 请求直接发送 FormData对象
// ...Ajax请求代码
xhr.send(fd)

监听 xhr.upload.onprogress 文件的上传进度

xhr.upload.onprogress = function(e) {
// e.lengthComputable 是一个布尔值,表示当前上传的资源是否具有可计算的长度
if (e.lengthComputable) {
// e.loaded 已传输的字节
// e.total 需传输的总字节
const percentComplete = Math.ceil((e.loaded / e.total) * 100)
}
}

监听 xhr.upload.onload 文件上传完成

xhr.upload.onload = function() {
$('#percent')
// 移除上传中的类样式
.removeClass()
// 添加上传完成的类样式
.addClass('progress-bar progress-bar-success')
}

jQuery-Ajax

浏览器中提供的 XMLHttpRequest 用法比较复杂,所以 jQuery 对 XMLHttpRequest 进行了封装,提供了一系列 Ajax 相关的函数,极大地降低了 Ajax 的使用难度。

常用方式

$.get()

$.get(url,[data],[callback])
参数名参数类型是否必选说明
urlstring请求的地址
dataobject请求传递的参数
callbackfunction请求成功的回调函数
// 例子
$.get('http://www.badui/api',{id:1,name:'fantasy'}, function(res) {
// 这里的 res 是服务器返回的数据
console.log(res)
})

$.post()

$.post(url,[data],[callback])
参数名参数类型是否必选说明
urlstring请求的地址
dataobject请求传递的参数
callbackfunction请求成功的回调函数
// 例子
$.post('http://www.badui/api',{id:1,name:'fantasy'}, function(res) {
// 这里的 res 是服务器返回的数据
console.log(res)
})

$.ajax()

$.ajax({
type: '', // 请求的方式,例如 GET 或 POST
url: '', // 请求的 URL 地址
data: { },// 这次请求要携带的数据
success: function(res) { } // 请求成功之后的回调函数
})
// 例子
$.ajax({
type: 'get', // 请求的方式,例如 GET 或 POST
url: 'http://www.badui/api', // 请求的 URL 地址
data: {id:1,name:'fantasy' },// 这次请求要携带的数据
success: function(res) { } // 请求成功之后的回调函数
})

FormDate 对象管理表单数据也适合 jQuery-Ajax
因为 FormDate 是 HTML5 新增的一个 对象,可以模拟表单操作
用法大致相同

拼接请求的根路径

建议新建 baseAPI.js

// 注意:每次调用 $.get() 或 $.post() 或 $.ajax() 的时候,
// 会先调用 ajaxPrefilter 这个函数
// 在这个函数中,可以拿到我们给Ajax提供的配置对象
$.ajaxPrefilter(function(options) {
// 在发起真正的 Ajax 请求之前,统一拼接请求的根路径
options.url = 'http://ajax.frontend.itheima.net' + options.url
})

统一为有权限的接口设置headers请求头

// 统一为有权限的接口,设置 headers 请求头 
if (options.url.indexOf('/my/') !== -1) {
options.headers = {
Authorization: localStorage.getItem('token') || ''
}
}
// 全局统一挂载 complete 回调函数
// 不论请求成功还是失败,最终都会调用 complete 回调函数
options.complete = function(res) {
// 在 complete 回调函数中,可以使用 res.responseJSON 拿到服务器响应回来的数据
if (res.responseJSON.status === 1 && res.responseJSON.message === '身份认证失败!') {
// 1. 强制清空 token
localStorage.removeItem('token')
// 2. 强制跳转到登录页面
location.href = '/login.html'
}
}


Axios

axios.get

// 语法
axios.get('url',{params:{ 参数 } } ).then(callback)
// 例子
axios.get('url', {
params :{
id: 1,
name:'fantasy'
} //res.data 是服务器返回的数据
}).then(res => { consloe.log(res.data) })
参数名参数类型是否必选说明
urlstring请求的地址
paramsobject请求传递的参数
callbackfunction请求成功的回调函数

axios.post

// 语法
axios.post('url',{ 参数 } ).then(callback)
// 例子
axios.post('url', {
id:1,
name:'fantasy'
}).then(res => { consloe.log(res.data) })
//res.data 是服务器返回的数据

axios

// 语法
axios({
// 使用 method 或 type 其中一种声明类型即可
method/type:'请求类型',
url:'请求地址',
data:{ post 数据 },
params:{ get 参数}
}).then(callback)

// 例子
axios({
method:'get',
url:'url',
params:{id:1,name:'fantasy'}
}).then(res => { consloe.log(res.data) })

配合 async / await 使用

axios返回的数据是一个Promise实例对象,用 .then()取到正确的数据

  • async 关键字用于函数上(async函数的返回值是Promise实例对象)
  • await 关键字用于 async 函数当中(await可以得到异步的结果)
// post 请求例子
document.querySelector('#btnPost').addEventListener('click', async function () {
// 如果调用某个方法的返回值是 Promise 实例,则前面可以添加 await!
// await 只能用在被 async “修饰”的方法中
// 解构赋值 把 axios 返回部分 解构出 data 重命名为 res
const { data: res } = await axios({
method: 'POST',
url: '/api/post',
data: {
name: 'fantasy',
id: 1
}
})

console.log(res)
})

vue 2.x 全局配置 axios

优点:每个组件可以通过 this.$http.get 直接发起请求,无需再导入 axios ;若根路径发生改变,只需修改 axios.defaults.baseURL ,有利于代码维护。

// main.js
// 配置请求根路径
axios.defaults.baseURL = 'http://api.com'

// 把 axios 挂载到 Vue 原型上
Vue.prototype.$http = aixos

缺点:无法实现 API 的复用。即多个组件需要对同一个接口发起请求,那么每个组件都需要重复书写 this.$http.get('/users') 类似的代码,造成冗余

改进:对于每一个根路径,独立封装一个 request.js 模块,组件导入所需根路径对应的 axios 进行使用

import axios from 'axios'

// 调用 axios.craete() 函数,request 接收 axios 实例对象
const request = axios.create({
baseURL: 'http://api.com'
})
export default request

评论



本站使用 Volantis 主题设计

:doodle { @grid: 1x5 / 100vmin; } @place-cell: center; width: @rand(45vmin, 75vmin); height: @rand(45vmin, 75vmin); transform: translate(@rand(-120%, 120%), @rand(-80%, 80%)) scale(@rand(.8, 2.8)) skew(@rand(45deg)); clip-path: polygon( @r(0, 30%) @r(0, 50%), @r(30%, 60%) @r(0%, 30%), @r(60%, 100%) @r(0%, 50%), @r(60%, 100%) @r(50%, 100%), @r(30%, 60%) @r(60%, 100%), @r(0, 30%) @r(60%, 100%) ); background: @pick(#f44336, #9c27b0, #673ab7, #3f51b5, #60569e, #e6437d, #ebbf4d, #00bcd4, #03a9f4, #2196f3, #009688, #5ee463, #f8e645, #ffc107, #ff5722, #43f8bf, #e136eb, #32ed39); opacity: @rand(.5, .9); position: relative; top: @rand(-80%, 80%); left: @rand(0%, 80%); animation: colorChange @rand(6.1s, 26.1s) infinite @rand(-.5s, -2.5s) linear alternate; @keyframes colorChange { 100% { left: 0; top: 0; filter: hue-rotate(360deg); } }