Skip to content

Commit

Permalink
change xmlhttprequest examples to fetch one and other fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonren0403 authored Oct 22, 2024
1 parent 28d2f3f commit 182f78f
Showing 1 changed file with 26 additions and 23 deletions.
49 changes: 26 additions & 23 deletions files/zh-cn/web/http/cors/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 标头字段来处理权限:
Expand Down Expand Up @@ -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("<person><name>Arun</name></person>");
const fetchPromise = fetch("https://bar.other/doc", {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "text/xml",
"X-PINGOTHER": "pingpong",
},
body: "<person><name>Arun</name></person>",
});

fetchPromise.then((response) => {
console.log(response.status);
});
```

上面的代码使用 `POST` 请求发送一个 XML 请求体,该请求包含了一个非标准的 HTTP `X-PINGOTHER` 请求标头。这样的请求标头并不是 HTTP/1.1 的一部分,但通常对于 web 应用很有用处。另外,该请求的 `Content-Type``application/xml`,且使用了自定义的请求标头,所以该请求需要首先发起“预检请求”。
Expand Down Expand Up @@ -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` 字段而引发了预检请求,则这一方法将无法使用。这种情况只能由服务端进行更改。
Expand All @@ -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)

Expand Down Expand Up @@ -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")}},该响应将被忽略,网络内容将无法使用

#### 预检请求和凭据

Expand Down

0 comments on commit 182f78f

Please sign in to comment.