javascript基础学习系列三百六十八:Request对象

javascript基础学习系列三百六十八:Request对象

顾名思义,Request 对象是获取资源请求的接口。这个接口暴露了请求的相关信息,也暴露了使

用请求体的不同方式。

注意 与请求体相关的属性和方法将在。

1. 创建 Request 对象

可以通过构造函数初始化 Request 对象。为此需要传入一个 input 参数,一般是 URL:

let r = new Request('https://foo.com');

console.log(r);

// Request {...}

Request 构造函数也接收第二个参数——一个 init 对象。这个 init 对象与前面介绍的 fetch() 的 init 对象一样。没有在 init 对象中涉及的值则会使用默认值:

// 用所有默认值创建 Request 对象 console.log(new Request(''));

// Request {

// bodyUsed: false

// cache: "default"

// credentials: "same-origin"

// destination: ""

// headers: Headers {}

Fetch API 提供了两种不太一样的方式用于创建 Request 对象的副本:使用 Request 构造函数和使 用 clone()方法。

将 Request 实例作为 input 参数传给 Request 构造函数,会得到该请求的一个副本:

let r1 = new

Request('https://foo.com');

let r2 = new Request(r1); console.log(r2.url); // https://foo.com/

如果再传入 init 对象,则 init 对象的值会覆盖源对象中同名的值:

let r1 = new Request('https://foo.com');

let r2 = new Request(r1, {method: 'POST'}); console.log(r1.method); // GET

console.log(r2.method); // POST

这种克隆方式并不总能得到一模一样的副本。最明显的是,第一个请求的请求体会被标记为“已使用”:

// integrity: ""

// keepalive: false

// method: "GET"

// mode: "cors"

// redirect: "follow"

// referrer: "about:client"

// referrerPolicy: ""

// signal: AbortSignal {aborted: false, onabort: null}

// url: ""

// }

// 用指定的初始值创建 Request 对象 console.log(new Request('https://foo.com',

{ method: 'POST' }));

// Request {

// bodyUsed: false

// cache: "default"

// credentials: "same-origin"

// destination: ""

// headers: Headers {}

// integrity: ""

// keepalive: false

// method: "POST"

// mode: "cors"

// redirect: "follow"

// referrer: "about:client"

// referrerPolicy: ""

// signal: AbortSignal {aborted: false, onabort: null}

// url: "https://foo.com/" // }

2. 克隆 Request 对象

let r1 = new Request('https://foo.com',

{ method: 'POST', body: 'foobar' });

console.log(r2.bodyUsed); // false 28

let r2 = new Request(r1);

console.log(r1.bodyUsed); // true

如果源对象与创建的新对象不同源,则 referrer 属性会被清除。此外,如果源对象的 mode 为 navigate,则会被转换为 same-origin。

第二种克隆 Request 对象的方式是使用 clone()方法,这个方法会创建一模一样的副本,任何值 都不会被覆盖。与第一种方式不同,这种方法不会将任何请求的请求体标记为“已使用”:

let r1 = new Request('https://foo.com', { method: 'POST', body: 'foobar' }); let r2 = r1.clone();

console.log(r1.url); // https://foo.com/

console.log(r2.url); // https://foo.com/

console.log(r1.bodyUsed); // false

console.log(r2.bodyUsed); // false

如果请求对象的 bodyUsed 属性为 true(即请求体已被读取),那么上述任何一种方式都不能用来 创建这个对象的副本。在请求体被读取之后再克隆会导致抛出 TypeError。

let r = new Request('https://foo.com'); r.clone();

new Request(r);

// 没有错误

r.text(); // 设置bodyUsed为true

r.clone();

// TypeError: Failed to execute 'clone' on 'Request': Request body is already used

new Request(r);

// TypeError: Failed to construct 'Request': Cannot construct a Request with a Request object that has already been used.

3. 在 fetch()中使用 Request 对象

fetch()和 Request 构造函数拥有相同的函数签名并不是巧合。在调用 fetch()时,可以传入已

经创建好的 Request 实例而不是 URL。与 Request 构造函数一样,传给 fetch()的 init 对象会覆 盖传入请求对象的值:

let r = new Request('https://foo.com');

// 向 foo.com 发送 GET 请求 fetch(r);

// 向 foo.com 发送 POST 请求 fetch(r, { method: 'POST' });

fetch()会在内部克隆传入的 Request 对象。与克隆 Request 一样,fetch()也不能拿请求体已 经用过的 Request 对象来发送请求:

let r = new Request('https://foo.com',

{ method: 'POST', body: 'foobar' });

r.text();

fetch(r);

// TypeError: Cannot construct a Request with a Request object that has already been used.

关键在于,通过 fetch 使用 Request 会将请求体标记为已使用。也就是说,有请求体的 Request 只能在一次 fetch 中使用。(不包含请求体的请求不受此限制。)演示如下:

let r = new Request('https://foo.com',

{ method: 'POST', body: 'foobar' });

fetch(r);

fetch(r);

// TypeError: Cannot construct a Request with a Request object that has already been used.

要想基于包含请求体的相同 Request 对象多次调用 fetch(),必须在第一次发送 fetch()请求前 调用 clone():

let r = new Request('https://foo.com',

{ method: 'POST', body: 'foobar' });

// 3 个都会成功 19 fetch(r.clone());

fetch(r.clone());

fetch(r);

相关推荐

手机号码估价查询
mobile365官网是多少

手机号码估价查询

📅 07-08 👁️ 4819
全民K歌如何删除播放记录
mobile365官网是多少

全民K歌如何删除播放记录

📅 07-01 👁️ 650
真实的和女生双飞经历 盘点有史以来双飞过程
365bet官网提现说维护

真实的和女生双飞经历 盘点有史以来双飞过程

📅 07-15 👁️ 6338