1、xhr
windows 的内置对象,XMLHttpRequest()
不封装的情况下,每次发送都需要调用 xhr.open()、xhr.send()
// 封装 xhr
function sendAJAX(params){
return new Promise((resolve, reject) => {
// 创建对象
let xhr = new XMLHttpRequest();
// 初始化
xhr.open(params.method, params.url);
// 发送
xhr.send();
// 事件绑定
xhr.onreadystatechange = function(){
if(xhr.readyState == 4) {
if(xhr.status >= 200 && xhr.status < 300){
resolve(xhr.response)
} else {
resolve(xhr.status)
}
}
}
})
}
// 使用 xhr 发送
sendAJAX({ method: 'GET', url: '请求地址' }).then(res => {
console.log("res", res)
}, err => {})
2、JQuery $ajax
对 XMLHttpRequest 的封装
有许多封装好的api, $.ajax、 $.get()、 $.post()
但是容易产生回调地狱
3、axios
对 XMLHttpRequest 的封装,返回的是一个 promise 对象
解决回调地狱的问题,但是会有 then 链式地狱(可以用 async await 解决)
api:axios.get()、 axios.post()、axios.put()、axios.delete()
// 简单使用
import axios from 'axios'
function sendAJAX(){
axios.get(`https:api.github.com/search/users?q=${keyword}`).then(response => {
console.log("获取数据成功了", response )
},error => {
console.log("获取数据失败了", error)
})
}
4、fetch
windows 的内置对象,与 XMLHttpRequest() 并列,浏览器可以直接使用,有兼容问题
关注分离的设计思想(实践步骤拆分), promise 风格
fetch 请求后返回的是一个 promise 对象,该 promise 是直接返回了服务器响应结果,并未直接展示返回数据(数据已经回来了),需要再调用返回对象的原型 json 方法获取一个 Promise对象,才能获取服务器返回数据
- 简单使用
// 发送网络请求 -- fetch (未优化)
search1 = () => {
fetch('http://localhost:3000/posts').then(response => {
console.log("联系服务器成功了", response)
// fetch 请求返回的 then 回调是返回服务器的响应结果,并未直接展示返回数据(数据已经回来了),需要再调用返回对象的原型 json 方法获取一个 Promise对象
return response.json()
},error => {
console.log("联系服务器失败了", error)
// 失败不往下走,返回初始化 Promise,中断 then 链式回调
return new Promise(() => {})
}).then(response => {
console.log("获取数据成功了", response)
},error => {
console.log("获取数据失败了", error)
})
}
// 发送网络请求 -- fetch (优化)
search2 = async () => {
try {
const response = await fetch('http://localhost:3000/posts')
const data = await response.json()
console.log("获取数据成功了", data)
} catch (error) {
console.log("获取数据失败了", error)
}
}
- fetch 封装
// request.js
export default async(url = '', data = {}, type = 'GET') => {
const baseUrl = "" // 基础路径
type = type.toUpperCase(); // 请求方式小写转换成大写
url = baseUrl + url; // 请求地址的拼接
if (type == 'GET') {
let dataStr = ''; //数据拼接字符串
Object.keys(data).forEach(key => {
dataStr += key + '=' + data[key] + '&';
})
if (dataStr !== '') {
dataStr = dataStr.substr(0, dataStr.lastIndexOf('&'));
url = url + '?' + dataStr;
}
}
let requestConfig = {
credentials: 'same-origin',
method: type,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
mode: "cors", // 用来决定是否允许跨域请求 值有 三个 same-origin,no-cors(默认)以及 cores;
cache: "force-cache" // 是否缓存请求资源 可选值有 default 、 no-store 、 reload 、 no-cache 、 force-cache 或者 only-if-cached 。
}
if (type == 'POST') {
Object.defineProperty(requestConfig, 'body', {
value: JSON.stringify(data)
})
}
try {
const response = await fetch(url, requestConfig);
const responseJson = await response.json();
return responseJson
} catch (error) {
throw new Error(error)
}
}
import api from '../request.js';
export const getX = (params) => api(`/api/...`, params)
export const postX = (params) => api(`/api/...`, params,'post')