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
这种克隆方式并不总能得到一模一样的副本。最明显的是,第一个请求的请求体会被标记为“已使用”:
let r1 = new Request(‘https://foo.com’,
{ method: ‘POST’, body: ‘foobar’ });
let r2 = new Request(r1);
console.log(r1.bodyUsed); // true
console.log(r2.bodyUsed); // false
如果源对象与创建的新对象不同源,则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.text(); // 设置bodyUsed 为true
r.clone();
// TypeError: Failed to execute ‘clone’ on ‘Request’: Request body is already used
new Request®;
// TypeError: Failed to construct ‘Request’: Cannot construct a Request with a
Request object that has already been used.
在fetch()中使用Request 对象
fetch()和Request 构造函数拥有相同的函数签名并不是巧合。在调用fetch()时,可以传入已
经创建好的Request 实例而不是URL。与Request 构造函数一样,传给fetch()的init 对象会覆
盖传入请求对象的值:
let r = new Request(‘https://foo.com’);
// 向foo.com 发送GET 请求
fetch®;
// 向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®;
// 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®;
fetch®;
// 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 个都会成功
fetch(r.clone());
fetch(r.clone());
fetch®;
javascript基础从小白到高手系列一千四百一十八:克隆Request 对象
最新推荐文章于 2024-07-17 22:06:28 发布