天天看点

react-native 网络请求fetch

前言:

官方推荐是网络请求Fetch 今天记录下这个Fetch
           

片段一:不同

Ajax  JQuery-Ajax  axios fetch区别: 

传统 Ajax   指的是 XMLHttpRequest(XHR)最早出现的发送后端请求技术,隶属于原始js中,核心使用XMLHttpRequest对象

JQuery-Ajax  是对原生XHR的封装,除此以外还增添了对JSONP的支持

axios  从浏览器中创建XMLHttpRequest  从node层发起http请求  支持 Promise API 
自动转json 客户端支持防止CSRF(因为从cookie里面获取key值后发送到服务端会检测).提供了一些并发请求的接口

Fetch  是基于promise设计的   脱离了XHR 
符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里  .更好更方便的写法 
           

片段二:缺点

fetch只对网络请求报错,对400,500都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致
请求不能完成时才会被 reject。
fetch默认不会带cookie,需要添加配置项: fetch(url, {credentials: 'include'})
fetch没有办法原生监测请求的进度,而XHR可以
           

片段三:真实的fetch

fetch 是一个 low-level 的 API,它注定不会像你习惯的 $.ajax 或是 axios 等库帮你封装各种各样的功能或实现。
也正是因为这个定位,在学习或使用 fetch API 时,你会遇到不少的挫折。
           

片段四:请求比你想象的要复杂

这是我对fetch的第一眼认识:
fetch('http://abc.com/tiger.png');
默认是get方法的form-data(也就是headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'})
原来需要 new XMLHttpRequest 等小十行代码才能实现的功能如今一行代码就能搞定,着实让人心动!
很可能会得到一个 401 Unauthorized 的结果,为什么?
会发现原来 fetch 在发送请求时默认不会带上 Cookie!
你需要:
fetch('/api/add?name=lucy', {
  credentials: 'include',
  ...
});
理,如果你需要 POST 一个 JSON 到服务端,你需要这样做:
fetch('/api/add', {  
  method: 'POST',
  credentials: 'include',
  headers: {
    'Content-Type': 'application/json;charset=UTF-8'
  },
  body: JSON.stringify({name: 'lucy'})
});
           

片段五 错误处理,比你想象的复杂

按照 MDN 的说法,fetch 只有在遇到网络错误的时候才会 reject 这个 promise,比如用户断网或请求地址的域名无法解析等。
所以只要服务器能够返回 HTTP 响应(甚至只是 CORS preflight 的 OPTIONS 响应),promise 一定是 resolved 的状态。
你的404,513,502等一律通过。这个就尴尬了。

判断一个 fetch 请求是不是成功呢?你得用 response.ok 这个字段。
fetch('xx.png')  
.then((response) => {
  if (response.ok) {
    console.log('ok');
  } else {
    thorw new error('network error');
  }
})
.catch(() => {
  console.log('error');
});
对数据格式处理 
fetch('/api/user.json?id=2')   // 服务端返回 {"name": "test", "age": 1} 字符串  
.then((response) => {
  // 这里拿到的 response 并不是一个 {name: 'test', age: 1} 对象
  return response.json();  // 将 response.body 通过 JSON.parse 转换为 JS 对象
})
.then(data => {
  console.log(data); // {name: 'test', age: 1}
});
           

啰嗦一句:

fetch 不支持同步请求   fetch不支持取消一个请求(使用 XMLHttpRequest 你可以用 

xhr.abort()

 方法取消一个请求)    fetch 无法查看请求的进度(使用 XMLHttpRequest 你可以通过 

xhr.onprogress

 回调来动态更新请求的进度)

继续阅读