资讯专栏INFORMATION COLUMN

fetch:不一样的xhr请求

cheng10 / 3416人阅读

摘要:无论请求成功与否,它都返回一个对象,对应请求的。可选一个配置项对象,包括所有对请求的设置。注意或方法的请求不能包含信息。只读请求所关联的对象。使用一个对象来读取流中的数据,并将状态改为已使用。

fetch初识

此功能某些浏览器尚在开发中,请参考浏览器兼容性表格以得到在不同浏览器中适合使用的前缀。由于该功能对应的标准文档可能被重新修订,所以在未来版本的浏览器中该功能的语法和行为可能随之改变。

Note: 如果不需要支持落后的IE系列浏览器,就可以放心大胆的使用吧!
ps: 当然也可以使用第三方的polyfill 库!https://github.com/github/fetch

fetch提供了对于xhr的这种请求中的常见的【请求 Request】、【响应 Response】两个对象的定义,就像node发起一个请求或者响应一个请求一样,创建了request、response两个实例对象,供使用者获取整个请求过程中的请求和响应信息。

它还提供了一种定义,将 CORS 和 HTTP 原生的头信息结合起来,取代了原来那种分离的定义。

fetch() 必须接受一个参数——资源的路径。无论请求成功与否,它都返回一个 promise 对象,resolve 对应请求的 Response。你也可以传一个可选的第二个参数—— init(参考 Request)。

一旦 Response 被返回,就有一些方法可以使用了,比如定义内容或者处理方法(参考 Body)。

你也可以通过 Request() 和 Response() 的构造函数直接创建请求和响应,但是我们不建议这么做。他们应该被用于创建其他 API 的结果(比如,service workers 中的 FetchEvent.respondWith)。

fetch由来

参考:https://developer.mozilla.org...
https://developer.mozilla.org...
https://developer.mozilla.org...
在这里可能需要先说下fetch方法的定义,其最原始的定义是在一个接口叫做GlobalFetch,该接口包含了GlobalFetch.fetch() 方法,Window 和WorkerGlobalScope都实现了GlobalFetch 接口,后来浏览器都把这个接口作了修改,形成了新的mixin,也就是WorkerOrGlobalScope,继而演变为:WindowOrWorkerGlobalScope,WindowOrWorkerGlobalScope混入【mixin】 了对 Window 和WorkerGlobalScope 接口的公共特性的描述【包括常见的setInterval、setTimeout等】。显然除了下文即将列出的之外,这些接口中的每一个,都可以增加更多的特性。

GlobalFetch =》 WorkerOrGlobalScope =》WindowOrWorkerGlobalScope

Note: WindowOrWorkerGlobalScope 是一个 mixin 而并非 interface。不能创建一个类型为 WindowOrWorkerGlobalScope 的对象。

由于 Window 和WorkerGlobalScope都实现了上述mixin,故而可以放心的在全局域下使用fetch,

fetch概念

Fetch 是一个现代的概念, 等同于 XMLHttpRequest。它提供了许多与XMLHttpRequest相同的功能,但被设计成更具可扩展性和高效性。
Fetch 的核心在于对 HTTP 接口的抽象,包括 Request,Response,Headers,Body,以及用于初始化异步请求的 global fetch。得益于 JavaScript 实现的这些抽象好的 HTTP 模块,其他接口能够很方便的使用这些功能。

Service Workers 是一个利用了 Fetch 实现的接口的例子。

除此之外,Fetch 还利用到了请求的异步特性——它是基于 Promise 的。

fettch使用

参考:https://developer.mozilla.org...
https://developer.mozilla.org...
这里先给出一个很简单的例子,以上代码中,我们通过网络获取了一个图片,然后将它插入到一个 标签中。这个最简单的用法中,fetch() 接受了一个参数——请求的地址——然后返回一个包含 response(一个 Response 对象)的 promise 对象。:

var myImage = document.querySelector("img");

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

这个例子很简单,不过还是需要先判断下是否支持fetch:

if(self.fetch) {
    // run my fetch request here
} else {
    // do something with XMLHttpRequest?
}

上面简单的例子已经包含了response对象、blob方法、then方法;后面一一简述;上面的例子中,fetch函数只是使用了一个参数,也就是url,即获取数据的后段地址,其实还有第二个参数 init对象;

var myHeaders = new Headers();

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

fetch("flowers.jpg",myInit)
.then(function(response) {
  return response.blob();
})
.then(function(myBlob) {
  var objectURL = URL.createObjectURL(myBlob);
  myImage.src = objectURL;
});

经过进一步的完善,fetch使用变成了这个样子。实际上fetch的定义是这样的:

Promise fetch(input[, init]);
//another to write the args of fetch 另一种书写方式
var myRequest = new Request(input, init);
Promise fetch(myRequest);
参数

参数的具体介绍:

参数
input
定义要获取的资源。这可能是:
一个 USVString 字符串,包含要获取资源的 URL。一些浏览器会接受 blob: 和 data: 作为 schemes.
一个 Request 对象。
init 可选
一个配置项对象,包括所有对请求的设置。可选的参数有:
method: 请求使用的方法,如 GET、POST。
headers: 请求的头信息,形式为 Headers 的对象或包含 ByteString 值的对象字面量。
body: 请求的 body 信息:可能是一个 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 对象。注意 GET 或 HEAD 方法的请求不能包含 body 信息。
mode: 请求的模式,如 cors、 no-cors 或者 same-origin。
credentials: 请求的 credentials,如 omit、same-origin 或者 include。为了在当前域名内自动发送 cookie , 必须提供这个选项, 从 Chrome 50 开始, 这个属性也可以接受 FederatedCredential 实例或是一个 PasswordCredential 实例。
cache:  请求的 cache 模式: default 、 no-store 、 reload 、 no-cache 、 force-cache 或者 only-if-cached 。
redirect: 可用的 redirect 模式: follow (自动重定向), error (如果产生重定向将自动终止并且抛出一个错误), 或者 manual (手动处理重定向). 在Chrome中,Chrome 47之前的默认值是 follow,从 Chrome 47开始是 manual。
referrer: 一个 USVString 可以是 no-referrer、client或一个 URL。默认是 client。
referrerPolicy: Specifies the value of the referer HTTP header. May be one of no-referrer、 no-referrer-when-downgrade、 origin、 origin-when-cross-origin、 unsafe-url 。
integrity: 包括请求的  subresource integrity 值 ( 例如: sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=)。
返回值
一个 Promise,resolve 时回传 Response 对象。

Exceptions
Type    Description
TypeError    Since Firefox 43, fetch() will throw a TypeError if the URL has credentials, such as http://user:password@example.com.

以上可以看到的就是所有的参数,同样也是有两种形式的书写:

myHeaders = new Headers({
  "Content-Type": "text/plain",
  "Content-Length": content.length.toString(),
  "X-Custom-Header": "ProcessThisImmediately",
});
//它的内容可以被获取:
console.log(myHeaders.has("Content-Type")); // true
console.log(myHeaders.has("Set-Cookie")); // false
myHeaders.set("Content-Type", "text/html");
myHeaders.append("X-Custom-Header", "AnotherValue"); //http 头部信息
var myInit = { method: "GET",
               headers: myHeaders,
               mode: "cors",
               cache: "default" };

fetch("flowers.jpg",myInit)
.then(function(response) {......
//或者使用这个来构建fetch参数,所需的参数和fetch所需的参数一样
var anotherRequest = new Request(input,myInit);

其中的头部有些需要注意,详情查看:https://developer.mozilla.org... 可以直接使用Headers构建新的请求头,headers是由键值对构成,不过有的请求头只允许用户代理做修改,详情参见:https://developer.mozilla.org...
同时Guard也是Headers中的重要部分,由于 Headers 可以在 request 请求中被发送或者在 response 请求中被接收,并且规定了哪些参数是可写的,Headers 对象有一个特殊的 guard 属性。这个属性没有暴露给 Web,但是它影响到哪些内容可以在 Headers 对象中被操作。

可能的值如下:

none:默认的

request:从 request 中获得的 headers(Request.headers)只读【后端获取http请求对象】

request-no-cors:从不同域(Request.mode no-cors)的 request 中获得的 headers 只读

response:从 response 中获得的 headers(Response.headers)只读

immutable:在 ServiceWorkers 中最常用的,所有的 headers 都只读
下面分别介绍request、body、response

request请求

了解了以上部分后,就知道可以构建request来发起http请求,

myHeaders = new Headers({
  "Content-Type": "text/plain",
  "Content-Length": content.length.toString(),
  "X-Custom-Header": "ProcessThisImmediately",
});
//它的内容可以被获取:
console.log(myHeaders.has("Content-Type")); // true
console.log(myHeaders.has("Set-Cookie")); // false
myHeaders.set("Content-Type", "text/html");
myHeaders.append("X-Custom-Header", "AnotherValue"); //http 头部信息

//属性
Request.method 只读
请求使用的方法 (GET, POST, 等.)
Request.url 只读
请求使用的 URL。
Request.headers 只读
请求所关联的 Headers 对象。
Request.context 只读  
请求的上下文 例如:(例如:audio, image, iframe, 等)
Request.referrer 只读
请求的来源 (例如:client).
Request.mode 只读
请求的模式 (例如: cors, no-cors, same-origin).
Request.credentials 只读
请求的凭证 (例如: omit, same-origin).
Request.redirect 只读
如何处理重定向模式 (例如: follow, error, or manual)
Request.integrity 只读
请求内容的 subresource integrity 值 (例如: sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=).
Request.cache 只读
请求的缓存模式 (例如: default, reload, no-cache).
Request implements Body, so it also has the following property available to it:

Body.bodyUsed 只读
指示body是否被使用, 类型为Boolean
body请求正文

不管是请求还是响应都能够包含body对象. body也可以是以下任意类型的实例.

ArrayBuffer
ArrayBufferView (Uint8Array and friends)
Blob/File
string
URLSearchParams
FormData
Body 类定义了以下方法 (这些方法都被 Request 和Response所实现)以获取body内容. 这些方法都会返回一个被解析后的promise对象和数据.

Body.bodyUsed 只读
包含一个指示body是否被读取过的 Boolean 值。
方法Edit

Body.arrayBuffer()
使用一个buffer数组来读取 Response流中的数据,并将bodyUsed状态改为已使用。
Body.blob()
使用一个Blob对象来读取 Response流中的数据,并将bodyUsed状态改为已使用。【二进制】
Body.formData()
使用一个 FormData 对象来读取 Response流中的数据,并将bodyUsed状态改为已使用【表单数据】。
Body.json()
使用一个 JSON 对象来读取 Response流中的数据,并将bodyUsed状态改为已使用【json】。
Body.text()
使用一个USVString (文本)
clone() 方法The clone() method of the Request interface creates a copy of the current Request object.

clone() throws a TypeError if the response Body has already been used. In fact, the main reason clone() exists is to allow multiple uses of Body objects (when they are one-use only.)

对象来读取 Response流中的数据,并将bodyUsed状态改为已使用。比起XHR来,这些方法让非文本化的数据使用起来更加简单,因为这些方法都被 Request 和Response所实现。

返回 response

如果遇到网络故障,fetch() promise 将会 reject,带上一个 TypeError 对象。虽然这个情况经常是遇到了权限问题或类似问题——比如 404 不是一个网络故障。想要精确的判断 fetch() 是否成功,需要包含 promise resolved 的情况,此时再判断 Response.ok 是不是为 true。
response的属性和方法:

Response.type 只读
包含Response的类型 (例如, basic, cors).
Response.url 只读
包含Response的URL.
Response.useFinalURL
包含了一个布尔值来标示这是否是该Response的最终URL.
Response.status 只读
包含Response的状态码 (例如, 200 成功).
Response.ok 只读
包含了一个布尔值来标示该Response成功(状态码200-299) 还是失败.
Response.statusText 只读
包含了与该Response状态码一致的状态信息 (例如, OK对应200).
Response.headers 只读
包含此Response所关联的Headers 对象.
Response 实现了 Body, 所以以下属性同样可用:

Body.bodyUsed 只读
 包含了一个布尔值来标示该Response是否读取过Body.
Response.clone()
创建一个Response对象的克隆
Response.error()
返回一个绑定了网络错误的新的Response对象
Response.redirect()
用另一个URL创建一个新的 response.
Response 实现了 Body, 所以以下方法同样可用

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84470.html

相关文章

  • fetch使用常见问题及其解决办法

    首先声明一下,本文不是要讲解fetch的具体用法,不清楚的可以参考MDN fetch教程。 引言 说道fetch就不得不提XMLHttpRequest了,XHR在发送web请求时需要开发者配置相关请求信息和成功后的回调,尽管开发者只关心请求成功后的业务处理,但是也要配置其他繁琐内容,导致配置和调用比较混乱,也不符合关注分离的原则;fetch的出现正是为了解决XHR存在的这些问题。例如下面代码: f...

    pubdreamcc 评论0 收藏0
  • 初识fetch

    摘要:后面可以跟对象,表示等待才会继续下去执行,如果被或抛出异常则会被外面的捕获。没有获取状态方法,标准没有提供获取当前状态或者的方法。只允许外部传入成功或失败后的回调。这种进度通知的功能还没有用过,暂不知道如何替代。 始终不是很懂fetch的作用,然后查了很多资料,看了一篇不错的文章,结合自己之前学习的Promise,然后做一篇文章,稍微记录一下。传统 Ajax 已死,Fetch 永生 虽...

    rickchen 评论0 收藏0
  • 分别使用 XHR、jQuery 和 Fetch 实现 AJAX

    摘要:本文详细讲述如何使用原生和来实现。使用可以无刷新地向服务端发送请求接收服务端响应,并更新页面。分别要用到的方法和方法。,,都是现在和未来解决异步的标准做法,可以完美搭配使用。这也是使用标准一大好处。 本文详细讲述如何使用原生 JS、jQuery 和 Fetch 来实现 AJAX。 AJAX 即 Asynchronous JavaScript and XML,异步的 JavaScript...

    Julylovin 评论0 收藏0
  • fetch使用常见问题及其解决办法

    摘要:首先声明一下,本文不是要讲解的具体用法,不清楚的可以参考教程。该模式用于跨域请求但是服务器不带响应头,也就是服务端不支持这也是的特殊跨域请求方式其对应的为。 首先声明一下,本文不是要讲解fetch的具体用法,不清楚的可以参考 MDN fetch教程。 fetch默认不携带cookie 配置其 credentials 项,其有3个值: omit: 默认值,忽略cookie的发送 sam...

    pkwenda 评论0 收藏0
  • 全面分析前端网络请求方式

    摘要:请求默认会携带同源请求的,而跨域请求则不会携带,设置的的属性为将允许携带跨域。类型请求成功后的回调函数。另外,同样提供了在环境下的支持,可谓是网络请求的首选方案。当网络故障时或请求被阻止时,才会标记为,如跨域不存在,网络异常等会触发。 一、前端进行网络请求的关注点 大多数情况下,在前端发起一个网络请求我们只需关注下面几点: 传入基本参数(url,请求方式) 请求参数、请求参数类型 设...

    Edison 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<