Fetch使用

MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch

2019.3.14 四 16:01

json 格式数据处理

最佳实践是在使用之前检查 content type 是否正确,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
fetch(myRequest).then(function(response) {
if(response.headers.get("content-type") === "application/json") {
return response.json().then(function(json) {
// process your JSON further
});
} else {
console.log("Oops, we haven't got JSON!");
}
});

// 其他
if(response.ok) {
return response.blob();
}

为什么我不再使用Fetch API开发应用

错误处理

我们需要加上一句 response.json() 来从 response 流对象中获取数据,但这只是一点很小的代价。

之前我提到的所有 http 工具库会把状态码错误的响应(比如404,500等)当成一个错误来处理,而 fetch 与 XMLHttpRequest 一样,只会在网络错误的情况下(比如 IP 地址无法解析,服务器不可访问或是不允许 CORS)reject 这个 promise。

POST 请求

fetch 是一种底层的 api,它不会在我们处理这种一般情形时带来便利,你必须清楚明确地使用它。首先,JSON 必须先转换成字符串,然后还要设置 ‘Content-Type’ 头部,指出实体的类型是 JSON,否则服务器会把它当做普通的字符串处理。
$PS: axios 有instance

默认行为

我的服务器使用基于 cookie 的认证方式,而 fetch 默认情况下不会发送 cookie
我的服务器需要知道客户端是否可以处理 JSON 数据
我的服务器在另一个子域名下,而 fetch 默认不启用 CORS
为了防御 XSRF 攻击,我的服务器要求每一个请求都必须带上一个 X-XSRF-TOKEN 头部,来证明请求确实是从我自己的页面发出的

fetch api不带cookie

fetch API 的一个特性是默认不发送 Cookie,只有设置适当的 credentials 时才会发送。

1
2
3
4
fetch('https://example.com', {
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, same-origin, *omit
})

[Fetch API Cookie问题

翻阅 Fetch Standard 才寻求到了答案。

A request has an associated credentials mode, which is “omit”, “same-origin”, or “include”. Unless stated otherwise, it is “omit”.

Request’s credentials mode controls the flow of credentials during a fetch. Credentials are HTTP cookies, TLS client certificates, and authentication entries. When request’s mode is “navigate”, its credentials mode is assumed to be “include” and fetch does not currently account for other values. If HTML changes here, this standard will need corresponding changes.

好嘛,Fetch 默认 credentials: ‘omit’ 。 那我们吧参数改成 include 就万事大吉了。

至于为什么 Fetch API 不带 cookie 一起飞,具体原因官方文档也有描述。

When request’s credentials mode is “include” it has an impact on the functioning of the CORS protocol other than including credentials in the fetch.

将 credentials 模式设置为 “include” 虽然能让请求包含 HTTP cookies TLS client certificates 和 authentication entries 这些内容,但它会影响到 CORS 协议的功能。

A request’s credentials mode is not necessarily observable on the server; only when credentials exist for a request can it be observed by virtue of the credentials being included. Note that even so, a CORS-preflight request never includes credentials.

请求的 credentials 模式没有必要对服务器可见,只有当 credentials 存在的时候才让服务器知晓。即便如此,CORS 预请求不会带上 credentials 。

The server developer therefore needs to decide whether or not responses “tainted” with credentials can be shared. And also needs to decide if requests necessitating a CORS-preflight request can include credentials. Generally speaking, both sharing responses and allowing requests with credentials is rather unsafe, and extreme care has to be taken to avoid the confused deputy problem.

开发人员应该自主决定是否确定要在请求内代上 credentials 。总之,无论是分发 responses 还是响应 requests,要带上 credentials 都是不安全的,开发人员需要非常注意这一点以避开这个派生问题。

16:36

knowledge is no pay,reward is kindness
0%