相关文章

React Native探索系列

前言

React Native可以使用多种方式来请求网络,比如fetch、XMLHttpRequest以及基于它们封装的框架,fetch可以说是替代XMLHttpRequest的产物,这一节我们就来学习fetch的基本用法。

1.get请求

fetch API是基于 Promise 设计的,因此了解Promise也是有必要的,推荐阅读MDN Promise教程

get请求访问淘宝IP库

我们先从最基础的get请求开始,get请求的地址为淘宝IP地址库,里面有访问接口的说明。请求代码如下所示。

  1. fetch('http://ip.taobao.com/service/getIpInfo.php?ip=59.108.51.32', {
  2. method: 'GET',
  3. headers: {
  4. 'Content-Type': 'application/json'
  5. }
  6. }).then((response) => {//1
  7. console.log(response);
  8. }).catch((err) => {//2
  9. console.error(err);
  10. });

其中method用于定义请求的方法,这里不用写method也可以,fetch默认的method就是GET。fetch方法会返回一个Promise对象,这个Promise对象中包含了响应数据response,也就是注释1处的response参数。在注释1处调用then方法将response打印在控制台Console中,then方法同样也会返回Promise对象,Promise对象可以进行链式调用,这样就可以通过多次调用then方法对响应数据进行处理。在注释2处通过catch方法来处理请求网络错误的情况。

除了上面这一种写法,我们还可以使用Request,如下所示。

  1. let request = new Request('http://liuwangshu.cn', {
  2. method: 'GET',
  3. headers: ({
  4. 'Content-Type': 'application/json'
  5. })
  6. });
  7. fetch(request).then((response) => {
  8. console.log(response);
  9. }).catch((err) => {
  10. console.error(err);
  11. });

我们先创建了Request对象,并对它进行设置,最后交给fetch处理。

为了验证fetch的get请求,需要添加触发get请求的代码逻辑,如下所示。

  1. import React, {Component} from 'react';
  2. import {AppRegistry, View, Text, StyleSheet, TouchableHighlight} from 'react-native';
  3. class Fetch extends Component {
  4. render() {
  5. return (
  6. <View style={styles.container}>
  7. <TouchableHighlight
  8. underlayColor='rgb(210,260,260)'
  9. style={{padding: 10, marginTop: 10, borderRadius: 5,}}
  10. onPress={this.get}
  11. >
  12. <Text >get请求</Text>
  13. </TouchableHighlight>
  14. </View>
  15. );
  16. }
  17. get() {
  18. fetch('http://ip.taobao.com/service/getIpInfo.php?ip=59.108.51.32', {
  19. method: 'GET',
  20. }).then((response) => {
  21. console.log(response);//1
  22. }).catch((err) => {//2
  23. console.error(err);
  24. });
  25. }
  26. }
  27. const styles = StyleSheet.create({
  28. container: {
  29. alignItems: 'center',
  30. }
  31. });
  32. AppRegistry.registerComponent('FetchSample', () => Fetch);

这里添加了一个TouchableHighlight,并定义了它的点击事件,一旦点击就会触发get方法请求网络。运行程序点击“get请求”,这时在控制台Console中就会显示回调的Response对象的数据,它包含了响应状态(status)、头部信息(headers)、请求的url(url)、返回的数据等信息。这次请求的响应状态status为200,返回的数据是JSON格式的,用Charles抓包来查看返回的JSON,如下图所示。

Response对象解析

Response对象中包含了多种属性:

  • status (number) : HTTP请求的响应状态行。
  • statusText (String) : 服务器返回的状态报告。
  • ok (boolean) :如果返回200表示请求成功,则为true。
  • headers (Headers) : 返回头部信息。
  • url (String) :请求的地址。

Response对象还提供了多种方法:

  • formData():返回一个带有FormData的Promise。
  • json() :返回一个带有JSON对象的Promise。
  • text():返回一个带有文本的Promise。
  • clone() :复制一份response。
  • error():返回一个与网络相关的错误。
  • redirect():返回了一个可以重定向至某URL的response。
  • arrayBuffer():返回一个带有ArrayBuffer的Promise。
  • blob() : 返回一个带有Blob的Promise。

接下来对返回的Response进行简单的数据处理,如下所示。

  1. get() {
  2. fetch('http://ip.taobao.com/service/getIpInfo.php?ip=59.108.23.12', {
  3. method: 'GET',
  4. headers: {
  5. 'Content-Type': 'application/json'
  6. }
  7. }).then((response) => response.json())//1
  8. .then((jsonData) => {//2
  9. let country = jsonData.data.country;
  10. let city = jsonData.data.city;
  11. alert("country:" + country + "-------city:" + city);
  12. });
  13. }

访问淘宝IP地址库会返回JSON数据,因此在注释1处调用response的json方法,将response转换成一个带有JSON对象的Promise,也就是注释2处的jsonData。最后取出jsonData中数据并展示在Alert中,这里data是一个对象,如果它是一个对象数组我们可以这样获取它的数据:

  1. let country=jsonData.data[0].country;

点击“get请求”,效果如下所示。

2.post请求

post请求的代码如下所示。

  1. post() {
  2. fetch('http://ip.taobao.com/service/getIpInfo.php', {
  3. method: 'POST',//1
  4. headers: {
  5. 'Content-Type': 'application/json',
  6. },
  7. body: JSON.stringify({//2
  8. 'ip': '59.108.23.12'
  9. })
  10. }).then((response) => response.json())
  11. .then((jsonData) => {
  12. let country = jsonData.data.country;
  13. let city = jsonData.data.city;
  14. alert("country:" + country + "-------city:" + city);
  15. });
  16. }

在注释1处将method改为POST,在注释2处添加请求的body。与get请求类似,这里也添加一个触发事件来进行post请求,当点击“post请求”时,查看Charles抓包的请求的信息,如下图所示。

可以看到请求数据是一个GSON字符串,因为淘宝IP库并不支持此类型的POST请求,所以不会返回我们需要的地理信息数据。

3.简单封装fetch

如果每次请求网络都要设定method、headers、body等数据,同时还要多次调用then方法对返回数据进行处理,显然很麻烦,下面就对上面例子中的get和post请求做一个简单的封装。

首先创建一个FetchUtils.js,代码如下所示。

  1. import React, {Component} from 'react';
  2. class FetchUtils extends React.Component {
  3. static send(method, url, data, callback) {
  4. let request;
  5. if (method === 'get') {
  6. request = new Request(url, {
  7. method: 'GET',
  8. headers: ({
  9. 'Content-Type': 'application/json'
  10. })
  11. });
  12. } else if (method === 'post') {
  13. request = new Request(url, {
  14. method: 'POST',
  15. headers: ({
  16. 'Content-Type': 'application/json'
  17. }),
  18. body: JSON.stringify(data)
  19. });
  20. }
  21. fetch(request).then((response) => response.json())
  22. .then((jsonData) => {
  23. callback(jsonData);//1
  24. });
  25. }
  26. }
  27. module.exports = FetchUtils;

在FetchUtils中定义了send方法,对GET和POST请求做了区分处理,并在注释1处通过callback将响应数据response回调给调用者。

最后调用FetchUtils的send方法,分别进行GET和POST请求:

  1. let FetchUtils=require('./FetchUtils');
  2. ...
  3. sendGet() {
  4. FetchUtils.send('get', 'http://ip.taobao.com/service/getIpInfo.php?ip=59.108.23.16', '', jsonData => {
  5. let country = jsonData.data.country;
  6. let city = jsonData.data.city;
  7. alert("country:" + country + "-------city:" + city);
  8. })
  9. }
  10. sendPost() {
  11. FetchUtils.send('post', 'http://ip.taobao.com/service/getIpInfo.php', {'ip': '59.108.23.16'}, jsonData => {
  12. let country = jsonData.data.country;
  13. let city = jsonData.data.city;
  14. alert("country:" + country + "-------city:" + city);
  15. })
  16. }

这样我们使用fetch访问网络时,只需要传入需要的参数,并对返回的jsonData 进行处理就可以了。

github源码

参考资料

Fetch API

fetch-issues-274

MDN Promise教程

ReactNative网络fetch数据并展示在listview中

React Native中的网络请求fetch和简单封装

在 JS 中使用 fetch 更加高效地进行网络请求

Using Fetch


欢迎关注我的微信公众号,第一时间获得博客更新提醒,以及更多成体系的Android相关原创技术干货。

扫一扫下方二维码或者长按识别二维码,即可关注。

React Native探索(五)使用fetch进行网络请求的更多相关文章

  1. React Native探索(四)Flexbox布局详解

    相关文章 React Native探索系列 前言 在Android开发中我们有很多种布局,比如LinearLayout和RelativeLayout,同样在React Native也有它的布局,这个布 ...

  2. ionic3 教程(五)基本的网络请求

    链接: ionic3教程(一)安装和配置 ionic3教程(二)登录页制作 ionic3教程(三)设置页制作 ionic3教程(四)安卓硬件返回键处理ionic3 教程(五)基本的网络请求 这是最后一 ...

  3. React Native 系列(五) -- 组件间传值

    前言 本系列是基于React Native版本号0.44.3写的.任何一款 App 都有界面之间数据传递的这个步骤的,那么在RN中,组件间是怎么传值的呢?这篇文章将介绍到顺传.逆传已经通过通知传值. ...

  4. React Native(十五)——RN中的分享功能

    终于,终于,可以总结自己使用RN时的分享功能了-- 为什么呢?且听我慢慢道来吧: 从刚开始接触React Native(2017年9月中旬)就着手于分享功能,直到自己参与公司的rn项目开发中,再到现在 ...

  5. React Native 系列(五)

    前言 本系列是基于React Native版本号0.44.3写的.任何一款 App 都有界面之间数据传递的这个步骤的,那么在RN中,组件间是怎么传值的呢?这篇文章将介绍到顺传.逆传已经通过通知传值. ...

  6. React Native使用NetInfo对当前系统网络的判断

    有网状态: 断网状态: 代码如下: 注意:第一次参考了http://www.hangge.com/blog/cache/detail_1614.html代码,一直显示的是unknow状态... 最后处 ...

  7. 用ES6和fetch封装网络请求

    导读: fetch: 这个方法是ES2017中新增的特性,这个特性出来后给人一种传统ajax已死的感觉,其实它的作用是替代浏览器原生的XMLHttpRequest异步请求,我们在日常的开发中,基本不会 ...

  8. 在React Native中,使用fetch网络请求 实现get 和 post

    //在React Native中,使用fetch实现网络请求 /* fetch 是一个封装程度更高的网络API, 使用了Promise * Promise 是异步编程的一种解决方案 * Promise ...

  9. React Native 网络请求封装:使用Promise封装fetch请求

    最近公司使用React作为前端框架,使用了异步请求访问,这里做下总结: React Native中虽然也内置了XMLHttpRequest 网络请求API(也就是俗称的ajax),但XMLHttpRe ...

随机推荐

  1. 在Ubuntu上安装Chrome浏览器和ChromeDriver

    启动脚本后报错 selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable may have w ...

  2. 第七课 GDB调试 (下)

    1序言: 通过前面一节第六课 GDB调试 (下)文章,可以掌握理解了gdb调试:怎么启动.运行,打断点.查看变量.甚至改变变量等的知识,今天来大概讲解下调试bug的类型. 2知识点: 2.1 就像之前 ...

  3. window下rails4.1 发生TZInfo::DataSourceNotFound 错误

    在官网上学习rails 4.1 ,启动rails server之后发生了如下错误 $ rails serverBooting WEBrickRails 4.1.0 application starti ...

  4. Java伪代码示例

    学习并转载自https://www.cnblogs.com/z245894546/p/7535261.html import.java.大道至简.*; import.java.愚公移山.*; publ ...

  5. IO流参考

    1 import java.io.File; import java.io.FileInputStream; /** * 读取一个字符 */ public class MyReadChar { pub ...

  6. Google揭露SHA-1碰撞,加速数据重删字节对比

    原创 架构师技术联盟  近期,Google和道荷兰阿姆斯特研究者宣布攻破了世界上第一例公开的SHA-1哈希碰撞实例,业界一片哗然.当两组不同的数据(文件.一段数据)计算出相同的Hash值时,即视为二者 ...

  7. 数据结构(二) 树Tree

    五.树 树的定义   树的逻辑表示:树形表示法.文氏图表示法.凹入表示法.括号表示法.         结点:表示树中的元素,包括数据项及若干指向其子树的分支. 结点的度:结点拥有的子树树:树的度:一 ...

  8. WIN10 安装Docker MySQL Ubuntu

    1)   必须专业版, 要开启 Hyper-V 2)下载安装包: 链接:https://pan.baidu.com/s/1APqcq2glvwzsCHlwRnPXkA 密码:wpej 3)安装时不要勾 ...

  9. [UOJ210]寻找罪犯

    2-sat神题.. 告诉是2-sat我也完全想不到正解. 看了看题解其实一步步分析也不算很难 这个题首先是要围绕每个人是否是犯人和每句话是否是真话来思考 首先要明确的是: 1.好人不说谎话 2.说了谎 ...

  10. java web 实体类生成

    工具下载地址:https://download.csdn.net/download/g342105676/10813246