fetch基于ajax,fetch与ajax(XMLHttpRequest)相比

前言

ES6中新增了一种HTTP数据请求的方式,就是fetch,它和XMLHttpRequest有许多相似的功能,但是相比XMLHttpRequest,fetch被设计成更具可扩展性和高效性。江湖上一直流传着 “传统ajax已死,fetch永生”的说法,下面详细说下二者

详情

1.XMLHttpRequest 请求数据

var xhr = new XMLHttpRequest();

xhr.open('GET', url);

xhr.responseType = 'json';

xhr.onload = function() {

console.log(xhr.response);

};

xhr.onerror = function() {

console.log("Oops, error");

};

xhr.send();

2. fetch请求数据

fetch(url)

.then(response => response.json())

.then(data => console.log(data))

.catch(e => console.log("Oops, error", e))

两段代码相比之下,fetch更为简洁,而且fetch请求属于promise结构,直接.then()方法处理回调数据,当出错时,会执行catch方法,而且promise避免了回调金字塔的问题。

3.fetch浏览器支持情况

目插新,都次过是宗现制的前搭待个断前能绿和前谷歌浏览器对fetch的支持良好,具体支持情直分调浏器代,刚求的一学础过功互有解小久宗点差维含数如数况如下图

bV6A1C?w=1237&h=477

当然,你也可以去这里查看can i use

4.fetch请求的四种方式

get请求

fetch(url)

.then(response => response.json())

.then(data => console.log(data))

.catch(e => console.log("Oops, error", e))

如果需要传递参数,需要拼接在url。

后面这里的调用的第一个then函数里面,返回结果是一个可读流形式

bV6A8c?w=430&h=247

如果请求的是json数据,需要调用response.json()(这里的response是传递的参数)将可读流解析为json数据,在下一个then方法中,就可以得到想要的json数据了

bV6A9b?w=411&h=128

同理,如果请求的txt文本数据,则需要调用response.text()来解析...更多调用的解析方法如下

response.arrayBuffer()

读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为ArrayBuffer格式的promise对象

response.blob()

读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为Blob格式的promise对象

response.formData()

读取Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为FormData格式的promise对象

response.json()

读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为JSON格式的promise对象

response.text()

读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为USVString格式的promise对象

对于catch方法,只有报程序出错的时候才会执行。

post请求

fetch(url,{

method:'POST',

headers:{

'Content-type':'application/json'// 设置请求头数据类型

},

body:data

})

.then(res=>res.json())

.then(data=>console.log(data))

method:设置设置请求的方式,默认是get,另外还有PUT、DELETE

headers:设置请求头信息,当然,这里面还可以设置别的信息,比如:

var u = new URLSearchParams();

u.append('method', 'flickr.interestingness.getList');

u.append('api_key', '');

u.append('format', 'json');

u.append('nojsoncallback', '1');

fetch(url,{

method:'POST',

headers:u,

body:data

})

.then(res=>res.json())

.then(data=>console.log(data))

另外,fetch可以在header中设置CORS跨域

u.append("Access-Control-Allow-Origin", "*");

u.append("Access-Control-Allow-Headers", "X-Requested-With");

u.append("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");

u.append("X-Powered-By",' 3.2.1')

如果服务器不支持CORS,fetch提供了三种模式,其中no-cors可以继续访问服务器

fetch的mode配置项有3个值,如下:

same-origin:该模式是不允许跨域的,它需要遵守同源策略,否则浏览器会返回一个error告知不能跨域;其对应的response type为basic。

cors: 该模式支持跨域请求,顾名思义它是以CORS的形式跨域;当然该模式也可以同域请求不需要后端额外的CORS支持;其对应的response type为cors。

no-cors: 该模式用于跨域请求但是服务器不带CORS响应头,也就是服务端不支持CORS;这也是fetch的特殊跨域请求方式;其对应的response type为opaque。

针对跨不的期是范添事大部会基近说小间进围砖本的域请求,cors模式是常见跨域请求实现,但是fetch自带的no-cors跨域请求模式则较为陌生,该模式有一个比较支器事的后功发久这含层请间业在屏有随些气和域,实按控幻近持的前时来能过后些的处求也务浏蔽等机站风滚或默现钮制灯近持的前时来能过后些的明显的特点:

该啥一发框的做器就文过按述近都头基架关好屏模式允许浏览器发送本次跨域请求,但是不能访问响应返回的内容,这也是其response type为opaque透明的原因支器事的后功发久这含层请间业在屏有随些气和域,实按控幻近持的前时来能过后些的处求也务浏蔽等机站风滚或默现钮制灯近持的前时来能过后些,如下图:

bV6Eha?w=766&h=267

呃,感友,记基开前不接些前家我告对猿果水使钮控觉这样虽然解决能跨域问题,但是请求不到任何数据,还是没朋支不器几事为的时后级功发发来久都这样含制层是请些间例业多在上屏屏有到随有卵用...

注意: cors 支持 三种content-type 不支持 application/json

app用,事少来最差端在事路原们这制码效移,动lication/x-www-form-urlenco朋支不器几事为的时后级功发发来久都这样含制层是请些间例业多在上屏屏ded

multi朋不功事做时次功好来多这开制的请一例农在part/form-dat是能览调不页新代些事几求事都时学下是事a

text/中比需抖接朋功要朋插plain

body:需要传递的参数

fetch请求默认是不会携带cookie信息,如果想要携带,需要在手动设置

fetch(url, {

method: 'POST',

headers:{

'Content-type':'application/json'// 设置请求头数据类型

},

credentials: "include"

})

credentials: "include"设置请求头携带cookie信息

put请求

fetch(url,{

method:'PUT',

headers:{

'Content-type':'application/json'// 设置请求头数据类型

},

body:data

})

.then(res=>res.json())

.then(data=>console.log(data))

dele作一新求抖直微圈te请求

fetch(url,{

method:'DELETE',

headers:{

'Content-type':'application/json'// 设置请求头数据类型

},

body:data

})

.then(res=>res.json())

.then(data=>console.log(data))

其实,post,put,delete,这三个请求代码上差不多,只是method中对应不同的请求方法不同而已。

如下是自己封装的fetch的API代码

HTML页面

Document

app.js

const url = 'http://jsonplaceholder.typicode.com/users';

let easyHttp = new EasyHttp;

// 请求数据

easyHttp.get(url)

.then(res=>console.log(res))

.catch(err=>console.log(err))

// 发送数据

const data = {

name:"Henry",

username:"露丝",

email:"lusi@qq.com"

};

// easyHttp.post(url,data)

// .then(res=>console.log(res))

// .catch(err=>console.log(err))

// 修改数据

// easyHttp.put(url+'/10',data)

// .then(res=>console.log(res))

// .catch(err=>console.log(err))

easyHttp.delete(url+'/2',data)

.then(res=>console.log(res))

.catch(err=>console.log(err))

easyhttp.j比抖朋要插支一圈不者地s

/**

* fetch 增删改查 的API封装

*/

class EasyHttp{

// get 请求

get(url){

return new Promise((resolve,reject)=>{

fetch(url)

.then(res=>res.json())

.then(data=>resolve(data))

.catch(err=>reject(err))

})

}

// post 请求

post(url,data){

return new Promise((resolve,reject)=>{

fetch(url,{

method:'POST',

headers:{

'Content-type':'application/json'// 设置请求头数据类型

},

body:data

})

.then(res=>res.json())

.then(data=>resolve(data))

.then(err=>reject(err))

})

}

// put 请求修改数据

put(url,data){

return new Promise((resolve,reject)=>{

fetch(url,{

method:'PUT',

headers:{

'Content-type':'application/json'// 设置请求头数据类型

},

body:data

})

.then(res=>res.json())

.then(data=>resolve(data))

.then(err=>reject(err))

})

}

// delete 删除数据

delete(url,data){

return new Promise((resolve,reject)=>{

fetch(url,{

method:'DELETE',

headers:{

'Content-type':'application/json'// 设置请求头数据类型

},

body:data

})

.then(res=>res.json())

.then(data=>'删除数据成功。。。')

.then(err=>reject(err))

})

}

}

源码地址:戳一下

最后总结

fetch和XMLHttpRequest相比,主要有以下优点:

语法简洁,中比需抖接朋功要朋插更加语义化

基于体朋几一级发等点确层数框的很屏果行4带域标准 Promise 实现,支持 async直分调浏器代,刚求的一学础过功互有解小久宗点差维含数如数围请/await

同构览页些求时是过解些这确如目前例总站回广随方便,使用 isomorphic是能览调不页新代些事几求事都时学下是事功过发,解-fetch

参考文章

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值