React-Native 之 网络请求 fetch

前言

  • 学习本系列内容须要具有必定 HTML 开发基础,没有基础的朋友能够先转至 HTML快速入门(一) 学习react

  • 本人接触 React Native 时间并非特别长,因此对其中的内容和性质了解可能会有所误差,在学习中若是有错会及时修改内容,也欢迎万能的朋友们批评指出,谢谢ios

  • 文章初版出自简书,若是出现图片或页面显示问题,烦请转至 简书 查看 也但愿喜欢的朋友能够点赞,谢谢web

网路请求


  • 在开发中,从网络上加载数据一直是重点和难点,尤为是在作相应的细节优化方面,在React Native 中一般是用哪一种方式加载网络数据呢?
    • React Native 中一般是经过 Ajax 从服务器获取数据,在 componentDidMount 方法中建立 Ajex 请求,等到请求成功,再用 this.setState 方法从新渲染UI

什么是 fetch


  • fetch 目前还不是 W3C 规范,是由 whatag 负责研发。与 Ajax 不一样的是,它的 API 不是事件机制,而是采用目前流行的 Promise(MDN Promise) 方式处理json

  • 格式:axios

fetch(url, init)
    .then((response) => {   // 数据解析方式
    })
    .then((responseData) => {       // 获取到的数据处理
    })
    .catch((error) => { // 错误处理
    })
    .done();
  • 上面的示例中的 init 是一个对象,他里面包含了:
    • method:请求方式(GET、POST、PUT等)。
    • headers:须要用到 Headers 对象使用这个参数。
    • body:须要发送的数据
    • mode:跨域设置(cors, no-cors, same-origin)
    • cache:缓存选项(default, no-store, reload, no-cache, force-cache, or only-if-cached)

译注:segmentfault

  • body:不可传对象,用JSON.stringify({...})也不能够,在jQuery 中会自动将对象封装成 formData 形式,fetch不会。
  • mode属性控制师傅跨域,其中 same-origin(同源请求,跨域会报error)、no-cors(默认,能够请求其它域的资源,不能访问response内的属性)和 cros(容许跨域,能够获取第三方数据,必要条件是访问的服务容许跨域访问)。
  • 使用 fetch 须要注意浏览器版本,但 React-Native 则不须要考虑。
  • response 对象能够有以下几种解析方式
    • arrayBuffer()
    • json()
    • text()
    • blob()
    • formData()
  • 下面是一个最基本的请求,只传入一个参数,默认为 GET 方式请求
fetch(url)
    .then((response) => response.json())        // json方式解析,若是是text就是 response.text()
    .then((responseData) => {   // 获取到的数据处理
    })
    .catch((error) => {     // 错误处理 
    })
    .done();
  • 针对表单提交的请求,咱们一般采用 POST 的方式。

方式一:react-native

fetch(url, {
        method: "POST",
        headers: {
            "Content-Type": "application/x-www-form-urlencoded"
        }
        body:"key1=value&key2=value…&keyN=value"
    })
    .then((response) => {       // 数据解析方式
    })
    .then((responseData) => {       // 获取到的数据处理
    })
    .catch((error) => { // 错误处理
    })
    .done();
  • JQuery 中,传入对象框架会自动封装成 formData 的形式,可是在 fetch 中没有这个功能,因此咱们须要本身初始化一个 FormData 直接传给 body (补充:FormData也能够传递字节流实现上传图片功能)

方式二:跨域

let formData = new FormData();
    formData.append("参数", "值");
    formData.append("参数", "值");
    
    fetch(url, {
        method:'POST,
        headers:{},
        body:formData,
        }).then((response)=>{
            if (response.ok) {
                return response.json();
            }
        }).then((json)=>{
            alert(JSON.stringify(json));
        }).catch.((error)=>{
            console.error(error);
        })

译注:浏览器

  • application/x-www-form-urlencoded: 窗体数据被编码为名称/值对。这是标准的编码格式。 multipart/form-data: 窗体数据被编码为一条消息,页上的每一个控件对应消息中的一个部分。 text/plain: 窗体数据以纯文本形式进行编码,其中不含任何控件或格式字符。
  • Fetch 跨域请求的时候默认是不带 cookie 的,若是须要进行设置 credentials:'include'。

获取 HTTP 头信息


console.log(response.headers.get('Content-Type'));
                        ...
    console.log(response.headers.get('Date'));

综合实例


译注:缓存

  • 下面内容整理自 React-Native 中文网

其余可用网路库


  • React Native 中已经内置了 XMLHttpRequest API,一些基于 XMLHttpRequest 封装的第三方库也可使用(如:axios、frisbee)但不能使用 jQuery,由于 jQuery 中还使用了不少浏览器才有而RN中没有的东西

    var request = new XMLHttpRequest();
        request.onreadystatechange = (e) => {
            if (request.readyState != 4) {
                return;
            }
    
            if (request.status === 200) {
                console.log('success', request.responseText);
            } else {
                console.warn('error');
            }
        }
    
        request.open('GET', 'https://mywebsite.com/endpoint/');
        request.send();
  • 注意:因为安全机制与网页环境有所不一样:在应用中你能够访问任何网站,没有跨域的限制

WebSocket

  • React Native 还支持 WebSocket,这种协议能够在单个TCP链接上提供全双工的通讯信道

    var ws = new WebSocket('ws://host.com/path');
    
        ws.onopen = () => {
            // 打开一个链接
            ws.send('something'); // 发送一个消息
        };
    
        ws.onmessage = (e) => {
            // 接收到了一个消息
            console.log(e.data);
        };
    
        ws.onerror = (e) => {
            // 发生了一个错误
            console.log(e.message);
        };
    
        ws.onclose = (e) => {
            // 链接被关闭了
            console.log(e.code, e.reason);
        };
相关文章
相关标签/搜索