From 182f78f61ec5d832d4c783065888880d86bb187e Mon Sep 17 00:00:00 2001
From: Jason Ren <40999116+jasonren0403@users.noreply.github.com>
Date: Tue, 22 Oct 2024 15:16:38 +0800
Subject: [PATCH] change xmlhttprequest examples to fetch one and other fixes
---
files/zh-cn/web/http/cors/index.md | 49 ++++++++++++++++--------------
1 file changed, 26 insertions(+), 23 deletions(-)
diff --git a/files/zh-cn/web/http/cors/index.md b/files/zh-cn/web/http/cors/index.md
index e6f1293469f2fa..f3c45fb3481d4b 100644
--- a/files/zh-cn/web/http/cors/index.md
+++ b/files/zh-cn/web/http/cors/index.md
@@ -84,12 +84,13 @@ CORS 请求失败会产生错误,但是为了安全,在 JavaScript 代码层
比如说,假如站点 `https://foo.example` 的网页应用想要访问 `https://bar.other` 的资源。`foo.example` 的网页中可能包含类似于下面的 JavaScript 代码:
```js
-const xhr = new XMLHttpRequest();
-const url = "https://bar.other/resources/public-data/";
+const fetchPromise = fetch("https://bar.other");
-xhr.open("GET", url);
-xhr.onreadystatechange = someHandler;
-xhr.send();
+fetchPromise
+ .then((response) => response.json())
+ .then((data) => {
+ console.log(data);
+ });
```
此操作实行了客户端和服务器之间的简单交换,使用 CORS 标头字段来处理权限:
@@ -148,12 +149,19 @@ Access-Control-Allow-Origin: https://foo.example
如下是一个需要执行预检请求的 HTTP 请求:
```js
-const xhr = new XMLHttpRequest();
-xhr.open("POST", "https://bar.other/resources/post-here/");
-xhr.setRequestHeader("X-PINGOTHER", "pingpong");
-xhr.setRequestHeader("Content-Type", "application/xml");
-xhr.onreadystatechange = handler;
-xhr.send("Arun");
+const fetchPromise = fetch("https://bar.other/doc", {
+ method: "POST",
+ mode: "cors",
+ headers: {
+ "Content-Type": "text/xml",
+ "X-PINGOTHER": "pingpong",
+ },
+ body: "Arun",
+});
+
+fetchPromise.then((response) => {
+ console.log(response.status);
+});
```
上面的代码使用 `POST` 请求发送一个 XML 请求体,该请求包含了一个非标准的 HTTP `X-PINGOTHER` 请求标头。这样的请求标头并不是 HTTP/1.1 的一部分,但通常对于 web 应用很有用处。另外,该请求的 `Content-Type` 为 `application/xml`,且使用了自定义的请求标头,所以该请求需要首先发起“预检请求”。
@@ -263,7 +271,7 @@ CORS 最初要求浏览器具有该行为,不过在后续的[修订](https://g
如果上面两种方式难以做到,我们仍有其他办法:
-1. 发出一个[简单请求](#简单请求)(使用 {{domxref("Response.url")}} 或 {{domxref("XMLHttpRequest.responseURL")}})以判断真正的预检请求会返回什么地址。
+1. 发出一个[简单请求](#简单请求)(使用 Fetch API 中的 {{domxref("Response.url")}} 或 {{domxref("XMLHttpRequest.responseURL")}})以判断真正的预检请求会返回什么地址。
2. 发出另一个请求(*真正*的请求),使用在上一步通过 `Response.url` 或 `XMLHttpRequest.responseURL` 获得的 URL。
不过,如果请求是由于存在 `Authorization` 字段而引发了预检请求,则这一方法将无法使用。这种情况只能由服务端进行更改。
@@ -278,20 +286,15 @@ CORS 最初要求浏览器具有该行为,不过在后续的[修订](https://g
本例中,`https://foo.example` 的某脚本向 `https://bar.other` 发起一个 GET 请求,并设置 Cookies。在 `foo.example` 中可能包含这样的 JavaScript 代码:
```js
-const invocation = new XMLHttpRequest();
const url = "https://bar.other/resources/credentialed-content/";
-function callOtherDomain() {
- if (invocation) {
- invocation.open("GET", url, true);
- invocation.withCredentials = true;
- invocation.onreadystatechange = handler;
- invocation.send();
- }
-}
+const request = new Request(url, { credentials: "include" });
+
+const fetchPromise = fetch(request);
+fetchPromise.then((response) => console.log(response));
```
-第 7 行将 {{domxref("XMLHttpRequest")}} 的 `withCredentials` 标志设置为 `true`,从而向服务器发送 Cookies。因为这是一个简单 `GET` 请求,所以浏览器不会对其发起“预检请求”。但是,如果服务器端的响应中未携带 {{HTTPHeader("Access-Control-Allow-Credentials")}}`: true`,浏览器将**不会**把响应内容返回给请求的发送者。
+本代码创建了一个 {{domxref("Request")}} 对象,并在构造器中将 `credentials` 选项设置为 `"include"`,然后将该请求作为 `fetch()` 的参数传递。因为这是一个简单 `GET` 请求,所以浏览器不会对其发起预检请求。但是,浏览器会**拒绝** 任何不带 {{HTTPHeader("Access-Control-Allow-Credentials")}}`: true` 标头的相应,且**不会**把响应提供给调用的网页内容。
![包含 Access-Control-Allow-Credentials 响应标头的简单 GET 请求的示意图](https://mdn.github.io/shared-assets/images/diagrams/http/cors/include-credentials.svg)
@@ -327,7 +330,7 @@ Content-Type: text/plain
[text/plain payload]
```
-即使第 10 行指定了 Cookie 是属于 `https://bar.other` 的内容的,但是,如果 `https://bar.other` 的响应中缺失 {{HTTPHeader("Access-Control-Allow-Credentials")}}`: true`(第 16 行),则响应内容会被忽略,不会提供给 web 内容。
+虽然请求的 `Cookie` 标头包含了为 `https://bar.other` 上的内容指定的 cookie,但如果 bar.other 没有像本例中演示的那样响应一个值为 `true` 的 {{HTTPHeader("Access-Control-Allow-Credentials")}},该响应将被忽略,网络内容将无法使用。
#### 预检请求和凭据