Fetch
浏览器 JavaScript 可以通过fetch
接口生成 HTTP 请求。 由于它比较新,所以它很方便地使用了Promise
(这在浏览器接口中很少见)。
fetch("example/data.txt").then(response => {
console.log(response.status);
// → 200
console.log(response.headers.get("Content-Type"));
// → text/plain
});
调用fetch
返回一个Promise
,它解析为一个Response
对象,该对象包含服务器响应的信息,例如状态码和协议头。 协议头被封装在类Map
的对象中,该对象不区分键(协议头名称)的大小写,因为协议头名称不应区分大小写。 这意味着header.get("Content-Type")
和headers.get("content-TYPE")
将返回相同的值。
请注意,即使服务器使用错误代码进行响应,由fetch
返回的Promise
也会成功解析。 如果存在网络错误或找不到请求的服务器,它也可能被拒绝。
fetch
的第一个参数是请求的 URL。 当该 URL 不以协议名称(例如http:
)开头时,它被视为相对路径,这意味着它解释为相对于当前文档的路径。 当它以斜线(/
)开始时,它将替换当前路径,即服务器名称后面的部分。 否则,当前路径直到并包括最后一个斜杠的部分,放在相对 URL 前面。
为了获取响应的实际内容,可以使用其text
方法。 由于初始Promise
在收到响应头文件后立即解析,并且读取响应正文可能需要一段时间,这又会返回一个Promise
。
fetch("example/data.txt")
.then(resp => resp.text())
.then(text => console.log(text));
// → This is the content of data.txt
有一种类似的方法,名为json
,它返回一个Promise
,它将解析为,将正文解析为 JSON 时得到的值,或者不是有效的 JSON,则被拒绝。
默认情况下,fetch
使用GET
方法发出请求,并且不包含请求正文。 你可以通过传递一个带有额外选项的对象作为第二个参数,来进行不同的配置。 例如,这个请求试图删除example/data.txt
。
fetch("example/data.txt", {method: "DELETE"}).then(resp => {
console.log(resp.status);
// → 405
});
405 状态码意味着“方法不允许”,这是 HTTP 服务器说“我不能这样做”的方式。
为了添加一个请求正文,你可以包含body
选项。 为了设置标题,存在headers
选项。 例如,这个请求包含Range
协议,它指示服务器只返回一部分响应。
fetch("example/data.txt", {headers: {Range: "bytes=8-19"}})
.then(resp => resp.text())
.then(console.log);
// → the content
浏览器将自动添加一些请求头,例如Host
和服务器需要的协议头,来确定正文的大小。 但是对于包含认证信息或告诉服务器想要接收的文件格式,添加自己的协议头通常很有用。