Response 对象包含一组只读属性,描述了请求完成后的状态,如下表所示。
属 性 值
headers 响应包含的Headers 对象
ok 布尔值,表示HTTP 状态码的含义。200~299 的状态码返回true,其他状态码返回false
redirected 布尔值,表示响应是否至少经过一次重定向
status 整数,表示响应的HTTP 状态码
statusText 字符串,包含对HTTP 状态码的正式描述。这个值派生自可选的HTTP Reason-Phrase 字段,因此如果服
务器以Reason-Phrase 为由拒绝响应,这个字段可能是空字符串
type 字符串,包含响应类型。可能是下列字符串值之一
basic:表示标准的同源响应
cors:表示标准的跨源响应
error:表示响应对象是通过Response.error()创建的
opaque:表示no-cors 的fetch()返回的跨源响应
opaqueredirect:表示对redirect 设置为manual 的请求的响应
url 包含响应URL 的字符串。对于重定向响应,这是最终的URL,非重定向响应就是它产生的
以下代码演示了返回200、302、404 和500 状态码的URL 对应的响应:
fetch(‘//foo.com’).then(console.log);
// Response {
// body: (…)
// bodyUsed: false
// headers: Headers {}
// ok: true
// redirected: false
// status: 200
// statusText: “OK”
// type: “basic”
// url: “https://foo.com/”
// }
fetch(‘//foo.com/redirect-me’).then(console.log);
// Response {
// body: (…)
// bodyUsed: false
// headers: Headers {}
// ok: true
// redirected: true
// status: 200
// statusText: “OK”
// type: “basic”
// url: “https://foo.com/redirected-url/”
// }
fetch(‘//foo.com/does-not-exist’).then(console.log);
// Response {
// body: (…)
// bodyUsed: false
// headers: Headers {}
// ok: false
// redirected: true
// status: 404
// statusText: “Not Found”
// type: “basic”
// url: “https://foo.com/does-not-exist/”
// }
fetch(‘//foo.com/throws-error’).then(console.log);
// Response {
// body: (…)
// bodyUsed: false
// headers: Headers {}
// ok: false
// redirected: true
// status: 500
// statusText: “Internal Server Error”
// type: “basic”
// url: “https://foo.com/throws-error/”
// }
克隆Response 对象
克隆Response 对象的主要方式是使用clone()方法,这个方法会创建一个一模一样的副本,不
会覆盖任何值。这样不会将任何请求的请求体标记为已使用:
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
有响应体的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