概述

要对XHR、Ajax,fetch有个深刻的掌握,让我们先来了解一下xhr、ajax、fetch 这三者都是个啥?以及他们的区别和联系。

首先,什么是XHR,XHR是XMLHttpRequest的缩写,它是是浏览器内置的一种对HTTP请求和响应的处理方式,能够获取和发送数据,支持流处理、进度事件和断点续传,是fetch和Ajax的基础。其次,那什么是ajax呢? ajax是Asynchronous JavaScript And XML(异步的JS和XML)的缩写,是一种实现无页面刷新的情况下使用XHR对象向服务器发起请求获取服务器端数据的技术。 它可以使用JSON、XML、html和text文本等格式发送和接收数据 ajax最吸引人的特性就是它的**“异步”**特性,也就是说可以 在不刷新页面的情况下实现与服务器的通信,交换数据,或更新页面。最后,那什么又是Fetch呢?Fetch是基于Promise的新式API,主要用于获取资源,支持流处理和通过拦截器来处理请求和响应,可以在浏览器端和Node.js中使用。

一次完整的ajax请求过程

创建网络请求的ajax对象(使用XHR)监听XHR对象状态的变化,或者监听onload事件(请求完成时触发)配置网络请求(通过open方法)发送send网络请求

// 1.创建XMLHttpReqest对象

const xhr = new XMLHttpRequest()

// 2.监听对象状态的改变(宏任务)

// 监听四种状态

// xhr.onreadystatechange = function() {

// // 1.如果状态不是DONE状态,直接返回

// if(xhr.readystate !== XMLHttpRequest.DONE) return

// // 2.确定拿到了数据

// console.log(xhr.response)

// }

// 监听onload事件,是可以确定拿到了数据的

xhr.onload = function() {

console.log(xhr.response)

}

// 3.配置请求的方式/URL等

xhr.responseType = "json"

xhr.timeout = 3000

xhr.open("get", "http://xxx.xx.xx", true)

// 4.发送请求

xhr.send()

// 5.获取数据

console.log(xhr.response)

XHR的state的说明

http的响应状态码的说明

客户端传递参数的四种方式

现在我们知道了一次完整的ajax的请求过程是什么样子,但是我们对于客户端发送请求传递的参数方式还不甚了解,接下来就一起来看一下吧

在开发中,我们使用最多的是get和post请求,在发送请求的过程中,我们也可以传递给服务器数据 常见的传递给服务器数据的有以下几种:

get请求的query参数post请求 x-www-form-urlencoded格式post请求FormData格式post请求JSON格式(最常用) 接下来看一下示例吧

客户端传递参数的四种方式

ajax网络请求过程的封装

方式1:普通封装

function myAjax({

url,

method = "get",

data = {},

timeout = 5000,

headers = {},

success,

failure

} = {}) {

// 1.创建xhr对象

const xhr = new XMLHttpRequest()

// 2.监听XHR对象状态的变化

xhr.onreadystatechange = function() {

if (xhr.readyState !== XMLHttpRequest.DONE) return

// 对网络请求返回的状态码进行处理

if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {

success && success(xhr.response)

} else {

failure && failure(xhr.response)

}

}

// 3.设置响应的类型

xhr.responseType = "json"

xhr.timeout = timeout

// 4.1 设置请求参数

const params = Object.keys(data)

.map(key => `${key}=${encodeURIComponent(data[key])}`)

const paramsString = params.join("&")

// 4.2 设置header,发送网络请求

if (method.toLowerCase() === "get") {

xhr.open(method, url + "?" + paramsString)

Object.keys(headers).forEach(headerKey => {

return xhr.setRequestHeader(headerKey, headers[headerKey])

})

xhr.send()

} else {

xhr.open(method, url)

xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')

Object.keys(headers).forEach(headerKey => {

return xhr.setRequestHeader(headerKey, headers[headerKey])

})

xhr.send(paramsString)

}

return xhr

}

方式2:基于Promise进行抽取封装

function myAjax({

url,

method = "get",

data = {},

timeout = 5000,

headers = {},

success,

failure

} = {}) {

const promise = new Promise((resolve, reject) => {

// 1.创建xhr对象

const xhr = new XMLHttpRequest()

// 2.监听XHR对象状态的变化

xhr.onreadystatechange = function() {

if (xhr.readyState !== XMLHttpRequest.DONE) return

// 对网络请求返回的状态码进行处理

if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {

resolve(xhr.response)

} else {

reject({ status: xhr.status, message: xhr.statusText })

}

}

// 3.设置响应的类型

xhr.responseType = "json"

xhr.timeout = timeout

// 4.1 设置请求参数

const params = Object.keys(data)

.map(key => `${key}=${encodeURIComponent(data[key])}`)

const paramsString = params.join("&")

// 4.2 设置header,发送网络请求

if (method.toLowerCase() === "get") {

xhr.open(method, url + "?" + paramsString)

Object.keys(headers).forEach(headerKey => {

return xhr.setRequestHeader(headerKey, headers[headerKey])

})

xhr.send()

} else {

xhr.open(method, url)

xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')

Object.keys(headers).forEach(headerKey => {

return xhr.setRequestHeader(headerKey, headers[headerKey])

})

xhr.send(paramsString)

}

})

promise.xhr = xhr

return promise

}

fetch网络请求

fetch可以看做是早期的XHR替代方案,它提供了一种更加现代化的处理方案: 比如:

返回值是一个Promise对象,可以优雅的对返回结果进行处理不像XHR一样,所有的操作都放在一个对象上

Fetch数据的响应

fetch的数据响应主要分为两个阶段: 阶段一:当服务器返回了响应(response)

fetch返回的promise就使用内建的Response class 对象来对响应头进行解析在这个阶段,可以通过检查响应头,来检查HTTP状态以确定请求是否成功如果fetch无法建立HTTP请求,例如网络问题,亦或是请求的网址不存在,那么promise就会reject异常的HTTP状态,例如404或500,不会导致error

可以在response的属性中看到HTTP状态:

status:HTTP状态码,例如200ok: 布尔值,如果HTTP状态码为200 - 299,则为true

阶段二:为了获取response body,我们需要使用一个其他的方法调用

response.text() – 读取response,并以文本形式返回responseresponse.json() – 将response解析为JSON

fetch网络请求的过程

基于Promise

fetch(url).then(res => {

console.log(res)

})

基于async、await的方案

async function getData() {

const res = await fetch(url)

const data = res.json()

console.log(data)

}

基于XHR和fetch进行文件上传

最后,我们来说一下基于XHR和fetch如何进行文件上传,看代码吧

XHR

基于XHR进行文件上传

fetch

基于fetch进行文件上传

好文链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: