Fetch

浏览器 JavaScript 可以通过fetch接口生成 HTTP 请求。 由于它比较新,所以它很方便地使用了Promise(这在浏览器接口中很少见)。

  1. fetch("example/data.txt").then(response => {
  2. console.log(response.status);
  3. // → 200
  4. console.log(response.headers.get("Content-Type"));
  5. // → text/plain
  6. });

调用fetch返回一个Promise,它解析为一个Response对象,该对象包含服务器响应的信息,例如状态码和协议头。 协议头被封装在类Map的对象中,该对象不区分键(协议头名称)的大小写,因为协议头名称不应区分大小写。 这意味着header.get("Content-Type")headers.get("content-TYPE")将返回相同的值。

请注意,即使服务器使用错误代码进行响应,由fetch返回的Promise也会成功解析。 如果存在网络错误或找不到请求的服务器,它也可能被拒绝。

fetch的第一个参数是请求的 URL。 当该 URL 不以协议名称(例如http:)开头时,它被视为相对路径,这意味着它解释为相对于当前文档的路径。 当它以斜线(/)开始时,它将替换当前路径,即服务器名称后面的部分。 否则,当前路径直到并包括最后一个斜杠的部分,放在相对 URL 前面。

为了获取响应的实际内容,可以使用其text方法。 由于初始Promise在收到响应头文件后立即解析,并且读取响应正文可能需要一段时间,这又会返回一个Promise

  1. fetch("example/data.txt")
  2. .then(resp => resp.text())
  3. .then(text => console.log(text));
  4. // → This is the content of data.txt

有一种类似的方法,名为json,它返回一个Promise,它将解析为,将正文解析为 JSON 时得到的值,或者不是有效的 JSON,则被拒绝。

默认情况下,fetch使用GET方法发出请求,并且不包含请求正文。 你可以通过传递一个带有额外选项的对象作为第二个参数,来进行不同的配置。 例如,这个请求试图删除example/data.txt

  1. fetch("example/data.txt", {method: "DELETE"}).then(resp => {
  2. console.log(resp.status);
  3. // → 405
  4. });

405 状态码意味着“方法不允许”,这是 HTTP 服务器说“我不能这样做”的方式。

为了添加一个请求正文,你可以包含body选项。 为了设置标题,存在headers选项。 例如,这个请求包含Range协议,它指示服务器只返回一部分响应。

  1. fetch("example/data.txt", {headers: {Range: "bytes=8-19"}})
  2. .then(resp => resp.text())
  3. .then(console.log);
  4. // → the content

浏览器将自动添加一些请求头,例如Host和服务器需要的协议头,来确定正文的大小。 但是对于包含认证信息或告诉服务器想要接收的文件格式,添加自己的协议头通常很有用。