资讯专栏INFORMATION COLUMN

React Native Fetch封装那点事...

CatalpaFlat / 2763人阅读

摘要:通过来对数据进行转化处理或最终暴露给调用者对异常的处理。封装在实际开发中,的都是相同的,不同的是请求的方法名与参数。上述提到的与的请求时机。下面来看下完整的封装。

每一门语言都离不开网络请求,有自己的一套Networking Api。React Native使用的是Fetch。 今天我们来谈谈与Fetch相关的一些事情。

purpose

通过这篇文章,你将了解到以下几点关于Fetch的独家报道

Fetch的简单运用

Fetch的主要Api

Fetch使用注意事项

Fetch的Promise封装

fetch

fetch的使用非常简单,只需传入请求的url

fetch("https://facebook.github.io/react-native/movies.json");

当然是否请求成功与数据的处理,我们还需处理成功与失败的回调

function getMoviesFromApiAsync() {
  return fetch("https://facebook.github.io/react-native/movies.json")
    .then((response) => response.json())
    .then((responseJson) => {
      return responseJson.movies;
    })
    .catch((error) => {
      console.error(error);
    });
}

通过response.json()将请求的返回数据转化成json数据以便使用。通过.then来对数据进行转化处理或最终暴露给调用者;.catch对异常的处理。

以上就是一个简单的网络请求,该请求默认是get方式。那么post又该如何请求呢?

Api & Note

在fetch中我们直接传入url进行请求,其实内部本质是使用了Request对象,只是将url出入到了Request对象中。

const myRequest = new Request("https://facebook.github.io/react-native/movies.json");
 
const myURL = myRequest.url; // https://facebook.github.io/react-native/movies.jsonflowers.jpg
const myMethod = myRequest.method; // GET
 
fetch(myRequest)
  .then(response => response.json())
  .then(responseJson => {
    //todo
  });

如果我们需要请求post,需要改变Request的method属性。

fetch("https://mywebsite.com/endpoint/", {
  method: "POST",
  headers: {
    Accept: "application/json",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    firstParam: "yourValue",
    secondParam: "yourOtherValue",
  }),
});

非常简单,在url后直接传入{}对象,其中指定method使用post。

相信大家应该都知道get与post的一个主要区别是get可以在url上直接添加参数,而post为了安全都不采用直接将参数追加到url上,而是使用body来传给service端。

在使用body前,这里还需知道headers。下面某个post请求的headers信息

需要注意的是Content-Type字段,它代表的是service端接收的数据类型,图片中使用的是application/x-www-form-urlencoded。这对于我们的body来说是非常重要的。只有匹配Content-Type的类型才能正确的传递参数信息。

示例的代码使用的是application/json,所以body使用Json.stringify()进行参数转换,而对于Content-Type为application/x-www-form-urlencoded,需要使用queryString.stringify()。

Request中除了method、headers与body,还有以下属性

Request.cache: 请求的缓存模式(default/reload/no-cache)

Request.context: 请求的上下文(audio/image/iframe)

Request.credentials: 请求的证书(omit/same-origin/include)

Request.destination: 请求的内容描述类型

Request.integrity: 请求的 subresource integrity

Request.mode: 请求的模式(cors/no-cors/same-origin/navigate)

Request.redirect: 请求的重定向方式(follow/error/manual)

Request.referrer: 请求的来源(client)

Request.referrerPolicy: 请求的来源政策(no-referrer)

Request.bodyUsed: 声明body是否使用在response中

请求成功之后,使用.then来转换数据,使用最多的是Body.json(),当然你也可以使用以下的几种数据转换类型

Body.arrayBuffer

Body.blob

Body.formData

Body.text

以上是fetch请求相关的属性与方法。如果你已经有所了解,那么恭喜你对fetch的基本使用已经过关了,下面对fetch的使用进行封装。

封装

在实际开发中,url的host都是相同的,不同的是请求的方法名与参数。而对于不同的环境(debug|release)请求的方式也可能不同。例如:在debug环境中为了方便调试查看请求的参数是否正确,我们会使用get来进行请求。所以在封装之前要明确什么是不变的,什么是变化的,成功与失败的响应处理。

经过上面的分析,罗列一下封装需要做的事情。

不变的: host,headers,body.json()

变化的: url,method,body

响应方式: Promise(resolve/reject)

function convertUrl(url, params) {
    let realUrl = ApiModule.isDebug?
        url + "?" + queryString.stringify(Object.assign({}, params, commonParams)) : url;

    if (ApiModule.isDebug) {
        console.log("request: " + realUrl);
    }
    return realUrl;
}

首先对url与参数params进行拼接,如果为debug模式将params拼接到url后。这里使用到了Object.assign()将params与commonParams组合成一个{}对象。最终通过queryString.stringify转化成string。

ApiModule.isDebug是原生传递过来的值,对于Android/IOS只需传递自己的ApiModule即可。
function getMethod() {
    return ApiModule.isDebug? "get": "post";
}

上述提到的get与post的请求时机。

const headers = {
    Accept: "application/json",
    "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
};

在headers中Content-Type类型为application/x-www-form-urlencode

function convertBody(params) {
    return ApiModule.isDebug? undefined : queryString.stringify(Object.assign({}, params, commonParams));
}

由于debug模式使用的是get方式,但get规定是不能有body的,所以这里使用了undefined来标识。同时为了匹配headers中的Content-Type,params的转化必须使用queryString.stringify;如果接受的是json,可以使用JSON.stringify。

定义完之后fetch对外只需接受params参数即可。

async function fetchRequest(params){
    let body = convertBody(params);
    fetch(convertUrl(baseUrl, params),{
        method: method,
        headers: headers,
        body: body
    })
    .then((response) => response.json())
    .then((responseJson) => {
        //todo success
    })
    .catch((error) => {
        if (ApiModule.isDebug) {
            console.error("request error: " + error);
        };
        //todo error
    });
}

fetch的请求封装完成,但我们的成功与失败的状态并没有通知给调用者,所以还需要一个回调机制。Promise是一个异步操作最终完成或者失败的对象。它可以接受两个函数resolve、reject

const p = new Promise((resolve, reject){
    ...
    //success
    resolve("success")
    //error
    reject("error")
});
//use
p.then(success => {
        console.log(success);
    }, error => {
          console.log(error)    
});

将fetch请求放入到Promise的异步操作中,这样一旦数据成功返回就调用resolve函数回调给调用者;失败调用reject函数,返回失败信息。而调用者只需使用Promise的.then方法等候数据的回调通知。下面来看下完整的fetch封装。

async function fetchRequest(params){
    let body = convertBody(params);
    return new Promise(function(resolve, reject){
        fetch(convertUrl(baseUrl, params),{
            method: method,
            headers: headers,
            body: body
        })
        .then((response) => response.json())
        .then((responseJson) => {
            resolve(responseJson);
        })
        .catch((error) => {
            if (ApiModule.isDebug) {
                console.error("request error: " + error);
            };
            reject(error);
        });
    });
}

之后对fetch的使用就非常简单了,只需传入需要的参数即可。

fetchRequest({method: "goods.getInfo", goodsId: 27021599158370074})
.then(res =>{
    this.setState({
        shareInfo: res.data.shareInfo
    });
});

以上是有关fetch的全部内容,当然在React Native中还有其它的第三方请求库:XMLHttpRequest,同时也支持WebSockets。感兴趣的也可以去了解一下,相信会有不错的收获。

精选文章

5分钟吃透React Native Flexbox

ViewDragHelper之手势操作神器

tensorflow-梯度下降,有这一篇就足够了

七大排序算法总结(java)

拉粉环节:感觉不错的可以来一波关注,扫描下方二维码,关注公众号,及时获取最新知识技巧。

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

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

相关文章

  • 移动端开发:架构点事

    摘要:移动精英开发社群的第期,也是围绕架构这个话题进行讨论。本次我们希望结合实际开发中遇到的问题,来聊聊移动端的架构设计。这样的模式改进一些,可能会更适合移动端架构。潘卫杰之前我们公司移动端的大项目就是插座式开发的,批量出各个行业的。 此前,58 同城的技术委员会执行主席沈剑在 OneAPM 的技术公开课上分享过一个主题,「好的架构不是设计出来的,而是演技出来的」。因为对很多创业公司而言,随...

    KnewOne 评论0 收藏0
  • 文件下载点事

    摘要:不过这种方式有问题,目前查到的大部分过程都是会在服务器新建出一个文件,等下载完毕在做删除,还没有找到可以跨过这一步的方式。 showImg(https://segmentfault.com/img/remote/1460000018850368); Content-Disposition / Content-Type Content-Disposition http 头部的 Conte...

    PascalXie 评论0 收藏0
  • pjax不再神秘,hash、state点事

    摘要:初步理解如果最近打电话给武汉的小伙伴,他说信号不好,那么相信我,他肯定不是真的信号不好,也不是不想和你说话,而是他可能在冰箱里。。。 初步理解 如果最近打电话给武汉的小伙伴,他说信号不好,那么相信我,他肯定不是真的信号不好,也不是不想和你说话,而是他可能在冰箱里。。。武汉的天气从来都是喜怒无常的,是吧,屌丝气十足,今年也是丝毫看不出有任何逆袭的迹象和可能性,当然咱也没必要去操那个心;好...

    solocoder 评论0 收藏0
  • SPA点事

    摘要:单页面应用的出现依然存在着争议性,我们该如何看待他的两面性呢接下来小生给大家总结一下他的优缺点。单页面应用的优势无刷新体验没有了令人诟病的页面频繁刷新,同时节约浏览器资源,路由响应比较及时,提升了用户的体验。 前端猿一天不学习就没饭吃了,后端猿三天不学习仍旧有白米饭摆于桌前。IT行业的快速发展一直在推动着前端技术栈在不断地更新换代,前端的发展成了互联网时代的一个缩影。而单页面应用的发展...

    PumpkinDylan 评论0 收藏0

发表评论

0条评论

CatalpaFlat

|高级讲师

TA的文章

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