javascript基础学习系列三百七十:克隆 Response 对象

克隆 Response 对象的主要方式是使用 clone()方法,这个方法会创建一个一模一样的副本,不 会覆盖任何值。这样不会将任何请求的请求体标记为已使用:

有响应体的 Response 对象只能读取一次。(不包含响应体的 Response 对象不受此限制。)比如:

let r = new Response('foobar');
r.text().then(console.log); // foobar
r.text().then(console.log);
// TypeError: Failed to execute 'text' on 'Response': body stream is locked

要多次读取包含响应体的同一个 Response 对象,必须在第一次读取前调用 clone():

let r = new 
Response('foobar');
r.clone().text().then(console.log); // foobar
r.clone().text().then(console.log); // foobar
r.text().then(console.log);         // foobar

此外,通过创建带有原始响应体的 Response 实例,可以执行伪克隆操作。关键是这样不会把第一 个 Response 实例标记为已读,而是会在两个响应之间共享:

let r1 = new Response('foobar');
    let r2 = new Response(r1.body);
    console.log(r1.bodyUsed);    // false
    console.log(r2.bodyUsed);    // false
    r2.text().then(console.log); // foobar
r1.text().then(console.log);
// TypeError: Failed to execute 'text' on 'Response': body stream is locked

Request、Response及Body混入

 let r1 = new Response('foobar'); let r2 = r1.clone();
    console.log(r1.bodyUsed); // false
    console.log(r2.bodyUsed); // false

如果响应对象的 bodyUsed 属性为 true(即响应体已被读取),则不能再创建这个对象的副本。在 响应体被读取之后再克隆会导致抛出 TypeError。

let r = new Response('foobar'); r.clone();
// 没有错误
r.text(); // 设置bodyUsed为true
    r.clone();
    // TypeError: Failed to execute 'clone' on 'Response': Response body is
    already used

Request 和 Response 都使用了 Fetch API 的 Body 混入,以实现两者承担有效载荷的能力。这个 混入为两个类型提供了只读的 body 属性(实现为 ReadableStream)、只读的 bodyUsed 布尔值(表 示 body 流是否已读)和一组方法,用于从流中读取内容并将结果转换为某种 JavaScript 对象类型。

通常,将 Request 和 Response 主体作为流来使用主要有两个原因。一个原因是有效载荷的大小 可能会导致网络延迟,另一个原因是流 API 本身在处理有效载荷方面是有优势的。除此之外,最好是一

Body 混入提供了 5 个方法,用于将 ReadableStream 转存到缓冲区的内存里,将缓冲区转换为某
种 JavaScript 对象类型,以及通过期约来产生结果。在解决之前,期约会等待主体流报告完成及缓冲被 解析。这意味着客户端必须等待响应的资源完全加载才能访问其内容。

1. Body.text()

Body.text()方法返回期约,解决为将缓冲区转存得到的 UTF-8 格式字符串。下面的代码展示了
在 Response 对象上使用 Body.text():

   fetch('https://foo.com')
      .then((response) => response.text())
      .then(console.log);
    // <!doctype html><html lang="en">
    //  <head>
    //   <meta charset="utf-8">
    //   ...

以下代码展示了在 Request 对象上使用 Body.text(): let request = new Request(‘https://foo.com’,

request.text()
  .then(console.log);
// barbazqux
{ method: 'POST', body: 'barbazqux' });

Body.json()

Body.json()方法返回期约,解决为将缓冲区转存得到的 JSON。下面的代码展示了在 Response
对象上使用 Body.json():

fetch('https://foo.com/foo.json')
      .then((response) => response.json())
      .then(console.log);
    // {"foo": "bar"}

以下代码展示了在 Request 对象上使用 Body.json(): let request = new Request(‘https://foo.com’,

request.json()
  .then(console.log);
// {bar: 'baz'}
{ method:'POST', body: JSON.stringify({ bar: 'baz' }) });

Body.formData()

浏览器可以将 FormData 对象序列化/反序列化为主体。例如,下面这个 FormData 实例:

let myFormData = new FormData();
myFormData.append('foo', 'bar');

在通过 HTTP 传送时,WebKit 浏览器会将其序列化为下列内容:

------WebKitFormBoundarydR9Q2kOzE6nbN7eR
Content-Disposition: form-data; name="foo"

Body.formData()方法返回期约,解决为将缓冲区转存得到的 FormData 实例。下面的代码展示 了在 Response 对象上使用 Body.formData():

   fetch('https://foo.com/form-data')
      .then((response) => response.formData())
      .then((formData) => console.log(formData.get('foo'));
    // bar

以下代码展示了在 Request 对象上使用 Body.formData(): let myFormData = new FormData();

   myFormData.append('foo', 'bar');
    let request = new Request('https://foo.com',
    request.formData()
      .then((formData) => console.log(formData.get('foo'));
    // bar
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值