前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React Native Fetch封装那点事...

React Native Fetch封装那点事...

作者头像
Rouse
发布2019-07-17 18:00:32
1.5K0
发布2019-07-17 18:00:32
举报
文章被收录于专栏:Android补给站

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

purpose

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

  • Fetch的简单运用
  • Fetch的主要Api
  • Fetch使用注意事项
  • Fetch的Promise封装

fetch

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

代码语言:javascript
复制
1fetch('https://facebook.github.io/react-native/movies.json');

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

代码语言:javascript
复制
 1function getMoviesFromApiAsync() {
 2  return fetch('https://facebook.github.io/react-native/movies.json')
 3    .then((response) => response.json())
 4    .then((responseJson) => {
 5      return responseJson.movies;
 6    })
 7    .catch((error) => {
 8      console.error(error);
 9    });
10}

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

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

Api & Note

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

代码语言:javascript
复制
 1const myRequest = new Request('https://facebook.github.io/react-native/movies.json');
 2
 3const myURL = myRequest.url; // https://facebook.github.io/react-native/movies.jsonflowers.jpg
 4const myMethod = myRequest.method; // GET
 5
 6fetch(myRequest)
 7  .then(response => response.json())
 8  .then(responseJson => {
 9    //todo
10  });

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

代码语言:javascript
复制
 1fetch('https://mywebsite.com/endpoint/', {
 2  method: 'POST',
 3  headers: {
 4    Accept: 'application/json',
 5    'Content-Type': 'application/json',
 6  },
 7  body: JSON.stringify({
 8    firstParam: 'yourValue',
 9    secondParam: 'yourOtherValue',
10  }),
11});

非常简单,在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)
代码语言:javascript
复制
1function convertUrl(url, params) {
2    let realUrl = ApiModule.isDebug?
3        url + "?" + queryString.stringify(Object.assign({}, params, commonParams)) : url;
4
5    if (ApiModule.isDebug) {
6        console.log("request: " + realUrl);
7    }
8    return realUrl;
9}

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

ApiModule.isDebug是原生传递过来的值,对于Android/IOS只需传递自己的ApiModule即可。

代码语言:javascript
复制
1function getMethod() {
2    return ApiModule.isDebug? "get": "post";
3}

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

代码语言:javascript
复制
1const headers = {
2    Accept: 'application/json',
3    "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
4};

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

代码语言:javascript
复制
1function convertBody(params) {
2    return ApiModule.isDebug? undefined : queryString.stringify(Object.assign({}, params, commonParams));
3}

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

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

代码语言:javascript
复制
 1async function fetchRequest(params){
 2    let body = convertBody(params);
 3    fetch(convertUrl(baseUrl, params),{
 4        method: method,
 5        headers: headers,
 6        body: body
 7    })
 8    .then((response) => response.json())
 9    .then((responseJson) => {
10        //todo success
11    })
12    .catch((error) => {
13        if (ApiModule.isDebug) {
14            console.error("request error: " + error);
15        };
16        //todo error
17    });
18}

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

代码语言:javascript
复制
 1const p = new Promise((resolve, reject){
 2    ...
 3    //success
 4    resolve('success')
 5    //error
 6    reject('error')
 7});
 8//use
 9p.then(success => {
10        console.log(success);
11    }, error => {
12          console.log(error)  
13});

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

代码语言:javascript
复制
 1async function fetchRequest(params){
 2    let body = convertBody(params);
 3    return new Promise(function(resolve, reject){
 4        fetch(convertUrl(baseUrl, params),{
 5            method: method,
 6            headers: headers,
 7            body: body
 8        })
 9        .then((response) => response.json())
10        .then((responseJson) => {
11            resolve(responseJson);
12        })
13        .catch((error) => {
14            if (ApiModule.isDebug) {
15                console.error("request error: " + error);
16            };
17            reject(error);
18        });
19    });
20}

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

代码语言:javascript
复制
1fetchRequest({method: "goods.getInfo", goodsId: 27021599158370074})
2.then(res =>{
3    this.setState({
4        shareInfo: res.data.shareInfo
5    });
6});

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-08-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Android补给站 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • purpose
  • fetch
  • Api & Note
  • 封装
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档