资讯专栏INFORMATION COLUMN

fetch与ajax(XMLHttpRequest)相比

diabloneo / 2351人阅读

摘要:前言中新增了一种数据请求的方式,就是,它和有许多相似的功能,但是相比被设计成更具可扩展性和高效性。该模式支持跨域请求,顾名思义它是以的形式跨域当然该模式也可以同域请求不需要后端额外的支持其对应的为。

前言 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的支持良好,具体支持情况如下图

当然,你也可以去这里查看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函数里面,返回结果是一个可读流形式

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

同理,如果请求的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,另外还有PUTDELETE
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")  
如果服务器不支持CORSfetch提供了三种模式,其中no-cors可以继续访问服务器

fetchmode配置项有3个值,如下:

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

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

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

针对跨域请求,cors模式是常见跨域请求实现,但是fetch自带的no-cors跨域请求模式则较为陌生,该模式有一个比较明显的特点:

该模式允许浏览器发送本次跨域请求,但是不能访问响应返回的内容,这也是其response type为opaque透明的原因,如下图:

呃,感觉这样虽然解决能跨域问题,但是请求不到任何数据,还是没有卵用...

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

application/x-www-form-urlencoded

multipart/form-data

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))
delete请求
 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.js
/**
 * 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))
        })
    }

 }

源码地址:戳一下

最后总结

fetchXMLHttpRequest相比,主要有以下优点:

语法简洁,更加语义化

基于标准 Promise 实现,支持 async/await

同构方便,使用 isomorphic-fetch

参考文章 MDN Fetch API ECMAScript 6 入门 Fetch相比Ajax有什么优势? 【fetch跨域请求】cors

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93637.html

相关文章

  • fetch 如何请求数据

    摘要:四请求常见数据格式接下来将介绍如何使用请求本地文本数据,请求本地数据以及请求网络接口。请求网络接口获取中的数据,做法与获取本地的方法类似得到数据后,同样要经过处理 一 序言 在 传统Ajax 时代,进行 API 等网络请求都是通过XMLHttpRequest或者封装后的框架进行网络请求,然而配置和调用方式非常混乱,对于刚入门的新手并不友好。今天我们介绍的Fetch提供了一个更好的替代方...

    MarvinZhang 评论0 收藏0
  • fetch 如何请求数据

    摘要:四请求常见数据格式接下来将介绍如何使用请求本地文本数据,请求本地数据以及请求网络接口。请求网络接口获取中的数据,做法与获取本地的方法类似得到数据后,同样要经过处理 一 序言 在 传统Ajax 时代,进行 API 等网络请求都是通过XMLHttpRequest或者封装后的框架进行网络请求,然而配置和调用方式非常混乱,对于刚入门的新手并不友好。今天我们介绍的Fetch提供了一个更好的替代方...

    Betta 评论0 收藏0
  • fetch 如何请求数据

    摘要:四请求常见数据格式接下来将介绍如何使用请求本地文本数据,请求本地数据以及请求网络接口。请求网络接口获取中的数据,做法与获取本地的方法类似得到数据后,同样要经过处理 一 序言 在 传统Ajax 时代,进行 API 等网络请求都是通过XMLHttpRequest或者封装后的框架进行网络请求,然而配置和调用方式非常混乱,对于刚入门的新手并不友好。今天我们介绍的Fetch提供了一个更好的替代方...

    jzman 评论0 收藏0
  • Ajax知识体系大梳理

    摘要:导读全称即异步与它最早在中被使用然后由推广开来典型的代表应用有以及现代网页中几乎无不欢前后端分离也正是建立在异步通信的基础之上浏览器为做了什么现代浏览器中虽然几乎全部支持但它们的技术方案却分为两种标准浏览器通过对象实现了的功能只需要通过一行 导读 Ajax 全称 Asynchronous JavaScript and XML, 即异步JS与XML. 它最早在IE5中被使用, 然后由Mo...

    Aomine 评论0 收藏0
  • ajax请求相关

    摘要:因为请求是异步的,我们无法获知请求的进度和响应状态,给我们提供了一个事件,我们可以通过监听这个时间来关注这种变化,所以下一步是注册事件。请求还没有被发送。方法已调用,请求已发送到服务器。到此,请求准备完全完成。 上一篇单独写的是ajax跨域,这一篇就来详细说一说ajax,ajax是现代web开发中必不可少的一部分内容,非常基础也非常重要,这篇总结一下到目前为止我对ajax的理解。 什么...

    h9911 评论0 收藏0

发表评论

0条评论

diabloneo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<