美文网首页
fetch详谈

fetch详谈

作者: 飘雪飞舞 | 来源:发表于2017-06-27 19:09 被阅读703次

简介

Fetch API 提供了一个 JavaScript接口,用于访问和操纵HTTP管道的部分,例如请求和响应。它还提供了一个全局 fetch()
方法,该方法提供了一种简单,合乎逻辑的方式来跨网络异步获取资源。

与ajax的区别

1.从 fetch()返回的 Promise 将不会拒绝HTTP错误状态, 即使响应是一个 HTTP 404 或 500。相反,它会正常解决 (其中ok状态设置为false), 并且仅在网络故障时或任何阻止请求完成时,它才会拒绝。
2.默认情况下, fetch在服务端不会发送或接收任何 cookies, 如果站点依赖于维护一个用户会话,则导致未经认证的请求(要发送 cookies,必须发送凭据头)。
说明:使用fetch模式,request header头是不会带cookies的,这样服务端就认为是不同的会话,解决方案:
设置fetch的options就好,我的如下:
const options= { method: "GET",mode: 'cors',credentials: 'include'};//same-origin
我因为用cors,所以credentials设置为include,如果不跨域,那么same-origin就行了。

特征检查

可以通过检查 Headers、Request、Response 或 fetch 在 window 或 worker 作用域中是否存在,来检查是否支持 Fetch API。

简单示例

fetch API中最常用的是fetch方法,该方法最简单的形式是,接受一个 URL 参数并返回以一个 promise 对象:

fetch("/data.json").then(function(res) {
  // res instanceof Response == true.
  if (res.ok) {
    res.json().then(function(data) {
      console.log(data.entries);
    });
  } else {
    console.log("Looks like the response wasn't perfect, got status", res.status);
  }
}, function(e) {
  console.log("Fetch failed!", e);
});

如果提交的是一个post请求

fetch("http://www.example.org/submit.php", {
  method: "POST",
  headers: {
    "Content-Type": "application/x-www-form-urlencoded"
  },
  body: "firstName=Nikhil&favColor=blue&password=easytoguess"
}).then(function(res) {
  if (res.ok) {
    alert("Perfect! Your settings are saved.");
  } else if (res.status == 401) {
    alert("Oops! You are not authorized.");
  }
}, function(e) {
  alert("Error submitting form!");
});

引入的接口

Fetch 引入了 3 个接口,分别是 Headers,Request 和 Response。

Headers

Headers 接口是一个简单的键值对:

var content = "Hello World";
var reqHeaders = new Headers();
reqHeaders.append("Content-Type", "text/plain"
reqHeaders.append("Content-Length", content.length.toString());
reqHeaders.append("X-Custom-Header", "ProcessThisImmediately");

也可以给构造函数传一个多维数组或 JS 字面量对象:

reqHeaders = new Headers({
  "Content-Type": "text/plain",
  "Content-Length": content.length.toString(),
  "X-Custom-Header": "ProcessThisImmediately",
});

结合fetch使用:

var myHeaders = new Headers();

var myInit = { method: 'GET',
               headers: myHeaders,
               mode: 'cors',
               cache: 'default' };

var myRequest = new Request('flowers.jpg', myInit);

fetch(myRequest).then(function(response) {
  return response.blob();
}).then(function(myBlob) {
  var objectURL = URL.createObjectURL(myBlob);
  myImage.src = objectURL;
});

Request

通过构造一个 Request 对象来获取网络资源,构造函数需要 URL、method 和 headers 参数,同时也可以提供请求体(body)、请求模式(mode)、credentials 和 cache hints 等参数。

var uploadReq = new Request("/uploadImage", {
  method: "POST",
  headers: {
    "Content-Type": "image/png",
  },
  body: "image data"
});

mode 参数用来决定是否允许跨域请求,以及哪些 response 属性可读。可选的 mode 值为 "same-origin"、"no-cors"(默认)以及 "cors"。

same-origin

该模式很简单,如果一个请求是跨域的,那么将返回一个 error,这样确保所有的请求遵守同源策略。

no-cors

该模式允许来自 CDN 的脚本、其他域的图片和其他一些跨域资源,但是首先有个前提条件,就是请求的 method 只能是HEAD
、GET 或 POST。此外,如果 ServiceWorkers 拦截了这些请求,它不能随意添加或者修改除这些之外 Header 属性。第三,JS 不能访问 Response 对象中的任何属性,这确保了跨域时 ServiceWorkers 的安全和隐私信息泄漏问题。

cors

该模式通常用于跨域请求,用来从第三方提供的 API 获取数据。该模式遵守 CORS 协议,并只有有限的一些 Header 被暴露给 Response 对象,但是 body 是可读的。例如,获取一个 Flickr 最感兴趣的照片的清单:

var u = new URLSearchParams();
u.append('method', 'flickr.interestingness.getList');
u.append('api_key', '<insert api key here>');
u.append('format', 'json');
u.append('nojsoncallback', '1');
 
var apiCall = fetch('https://api.flickr.com/services/rest?' + u);
 
apiCall.then(function(response) {
  return response.json().then(function(json) {
    // photo is a list of photos.
    return json.photos.photo;
  });
}).then(function(photos) {
  photos.forEach(function(photo) {
    console.log(photo.title);
  });
});

另外,credentials 属性决定了是否可以跨域访问 cookie 。该属性与 XHR 的
withCredentials 标志相同,但是只有三个值,分别是 omit(默认)、same-origin 和 include。

Response

Response 对象通常在 fetch() 的回调中获得,也可以通过 JS 构造,不过这通常只在 ServiceWorkers 中使用。

处理 body

在 Request 和 Response 对象中都可能有 body
属性,并且 body
可以是各种类型,比较复杂,所以前面我们故意先跳过它,在这里单独拿出来讲解。
body
可以是以下任何一种类型的实例:
ArrayBuffer
ArrayBufferView (Uint8Array and friends)
Blob/File
string
URLSearchParams
FormData —— 目前不被 Gecko 和 Blink 支持,Firefox 预计在版本 39 和 Fetch 的其他部分一起推出

Fetch和promise不足

1.不能中断,没有 abort、terminate、onTimeout 或 cancel 方法
2.缺少其它一些方法:always,progress,finally
3.没有 Deferred
4.没有获取状态方法:isRejected,isResolved

相关文章

网友评论

      本文标题:fetch详谈

      本文链接:https://www.haomeiwen.com/subject/efvecxtx.html