龙空技术网

fetch-新时代的 Ajax

前端圈 1802

前言:

此刻大家对“ajax什么时候出现”大概比较关切,看官们都想要剖析一些“ajax什么时候出现”的相关知识。那么小编也在网上收集了一些关于“ajax什么时候出现””的相关资讯,希望你们能喜欢,姐妹们一起来学习一下吧!

jQuery 当初的流行带来了一个很重要的 API 那就是 $.ajax() 相信很多同学都深爱过它,究其原因是原生 XMLHttpRequest 的不友好,只能借助第三方框架来发送 Ajax 请求,近来也出现了更多好用的框架,比如 axios,难道真的就只能借助第三方框架来做这个事吗?

还真不是,新推出的 Fetch API 就是用来替代 XMLHttpRequest 的,功能类似,更具可扩展性和高效性。我们来看一个简单的例子

fetch('').then(function(response) { return response.json()}).then(function(data) { console.log(data)})

注意,这和使用 axios 是不一样的,并非一次到位就能拿到响应 body,而是要经过两次 Promise.then(),当然我们可以很容易地将其变成 async await 的方式

let fetchData = async () => { let response = await fetch('') let data = await response.json()}

fetch() 方法返回的是一个 Response 对象,结构如下

{ body: ReadableStream, bodyUsed: false, headers: Headers, ok: true redirected: false status: 200 statusText: "OK" type: "cors", url: ""}

这里的响应正文 body 实际上是一个流,很明显是不能直接使用的,只能通过下面的方法来获取不同格式的内容

Body.arrayBuffer() 使用 buffer 数组来读取Body.blob() 使用 Blob 对象来读取Body.formData() 使用 FormData 对来读取Body.json() 使用 JSON 对来读取Body.text() 使用文本对来读取

比如下载一张图片并用 <img> 标签显示(注意跨域)

<img id="imgbox">....let setImg = async () => { let response = await fetch('') let data = await response.blob() let objectURL = URL.createObjectURL(data) let myImage = document.querySelector('#imgbox') myImage.src = objectURL}

不管使用上面哪种读取方式,body 只能被读取一次,然后 bodyUsed 的值都会被修改成 true,表示已被使用,之后就不能再读取了。

let fetchData = async () => { let response = await fetch('') console.log('bodyUsed', response.bodyUsed) let data = await response.json() console.log('bodyUsed', response.bodyUsed) let dataAgain = await response.json() console.log('dataAgain', dataAgain)}fetchData()// bodyUsed false// bodyUsed true// Uncaught (in promise) TypeError: Failed to execute 'json' on 'Response': body stream is locked

可以看到,试图再次读取 body 是会报错的,如果我就是想要多次读取呢?我们可以使用 clone() 方法将 Response对象克隆一个出来

let fetchData = async () => { let response = await fetch('') let clone1 = response.clone() let clone2 = response.clone() let data = await response.json() let data1 = await clone1.json() let data2 = await clone2.json() console.log(data, data1, data2) // [data] [data] [data] }

注意,每个克隆的对象也只能用一次,要实现多次读取就只能是克隆多个出来。

fetch() 不是只能发送 GET 请求,所有方法的请求都能发送,这取决于它的第二个参数,我们来看看 fetch 的实际语法

fetch(input[, init])
input 一个 URL 或者 Request 对象init 可选参数,请求配置(method:请求方法,headers 请求头 body请求体...)

比如要发送一个 POST 请求

let submit = async () => { await fetch(url, { method: 'POST', body: JSON.stringify(data) })}

当然也可以用 Request 构造一个对象传入 fetch

let submit = async () => { let _request = new Request(url, { method: 'POST', body: JSON.stringify(data) } await fetch(_request)}

要让请求携带请求头需要用 Headers() 构造函数来创建一个自己的 headers 对象

let submit = async () => { let headers = new Headers({ 'Content-Type': 'application/json' }) headers.append('token', 'xxx') fetch(url, { method: 'POST', body: JSON.stringify(data), headers: headers })}

如果我要发送一个表单数据呢?可以通过 FormData() 构造函数基于 form 标签构建一个对象出来

var form = new FormData(document.getElementById('login-form'))fetch("/login", { method: "POST", body: form})

除了 IE(非 Edge)目前主流的浏览器都支持 fetch,如果你有更高的兼容性需求,也可以加上 fetch 的 polyfil:

标签: #ajax什么时候出现