Request 表示一个请求类,需要通过实例化来生成一个请求对象。通过该对象可以描述一个 HTTP 请求中的请求(一般含有请求头和请求体)。既然是用来描述请求对象,那么该请求对象应该具有修改请求头(Headers)和请求体(Body)的方式。下面我们先来看下规范中 Request 具有哪些接口:

  1. typedef (Request or USVString) RequestInfo;
  2. [Constructor(RequestInfo input, optional RequestInit init),
  3. Exposed=(Window,Worker)]
  4. interface Request {
  5. readonly attribute ByteString method;
  6. readonly attribute USVString url;
  7. [SameObject] readonly attribute Headers headers;
  8. readonly attribute RequestDestination destination;
  9. readonly attribute USVString referrer;
  10. readonly attribute ReferrerPolicy referrerPolicy;
  11. readonly attribute RequestMode mode;
  12. readonly attribute RequestCredentials credentials;
  13. readonly attribute RequestCache cache;
  14. readonly attribute RequestRedirect redirect;
  15. readonly attribute DOMString integrity;
  16. readonly attribute boolean keepalive;
  17. readonly attribute boolean isReloadNavigation;
  18. readonly attribute boolean isHistoryNavigation;
  19. readonly attribute AbortSignal signal;
  20. [NewObject] Request clone();
  21. };
  22. Request includes Body;
  23. dictionary RequestInit {
  24. ByteString method;
  25. HeadersInit headers;
  26. BodyInit? body;
  27. USVString referrer;
  28. ReferrerPolicy referrerPolicy;
  29. RequestMode mode;
  30. RequestCredentials credentials;
  31. RequestCache cache;
  32. RequestRedirect redirect;
  33. DOMString integrity;
  34. boolean keepalive;
  35. AbortSignal? signal;
  36. any window; // can only be set to null
  37. };
  38. enum RequestDestination { "", "audio", "audioworklet", "document", "embed", "font", "image", "manifest", "object", "paintworklet", "report", "script", "sharedworker", "style", "track", "video", "worker", "xslt" };
  39. enum RequestMode { "navigate", "same-origin", "no-cors", "cors" };
  40. enum RequestCredentials { "omit", "same-origin", "include" };
  41. enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" };
  42. enum RequestRedirect { "follow", "error", "manual" };
  43. // 来自 https://fetch.spec.whatwg.org/#request-class

规范中定义的接口我们可以对应着 MDN 进行查看,你可以点击这里更直观的看看它有哪些属性和方法供我们使用,这里不做一一解释。

注意这里的属性都是只读的,规范中我们可以看到构造函数的第一个参数为 Request 对象或字符串,我们一般采取字符串,即需要访问的资源地址( HTTP 接口地址)。第二个参数接收一个 RequestInit 可选对象,而这个对象是一个字典。在 javascript 中,我们可以理解为一个对象({})。RequestInit 里面我们可以配置初始属性,告诉 Request 我们这个请求的一些配置信息。

这里我们需要对以下几个属性特别注意下。

mode 是一个 RequestMode 枚举类型,可取的值有 navigate, same-origin, no-cors, cors。它表示的是一个请求时否使用 CORS,还是使用严格同源模式。当处于跨域情况下,你应当设置为 cors。该值的默认值在使用 Request 初始化时,默认为 cors。当使用标记启动的嵌入式资源,例如 <link><script>标签(未手动修改 crossorigin 属性),默认为 no-cors。详细信息请参考 whatwg 规范或 MDN

credentials 是一个 RequestCredentials 枚举类型,可取的值有 omit, same-origin, include。它表示的是请求是否在跨域情况下发送 cookie。看到这,如果对 XHR 了解的同学应该很熟悉。这和 XHR 中的 withCredentials 很相似。但是 credentials 有三个可选值,它的默认值为 same-origin。当你需要跨域传递 cookie 凭证信息时,请设置它为 include。注意这里有一个细节,当设置为 include 时,请确保 Response HeaderAccess-Control-Allow-Origin 不能为 *,需要指定源(例如:http://127.0.0.1:4001),否则会你将会在控制台看到如下错误信息。详细信息请参考 whatwg 规范或 MDN

The value of the ‘Access-Control-Allow-Origin’ header in the response must not be the wildcard ‘*’ when the request’s credentials mode is ‘include’.

你可以使用文章中提供的代码中启动 cors 示例代码,然后在浏览器中输入 http://127.0.0.1:4001/request,如果不出意外的话,你可以在控制台中看到上面的错误提示

body 是一个 BodyInit 类型。它可取的值有 Blob,BufferSource , FormData , URLSearchParams , ReadableStream , USVString。细心的同学不知道有没有发现,我们常见的 json 对象却不在其中。因此,我们如果需要传递 json 的话,需要调用 JSON.stringify 函数来帮助我们转换成字符串。

下面将给出一段示例代码。

示例

示例代码地址:https://github.com/GoDotDotDot/fe9-fetch-demo/blob/master/views/request.html#L24

打开浏览器输入:http://127.0.0.1:4000/request

  1. // 客户端
  2. const headers = new Headers({
  3. 'X-Token': 'fe9',
  4. });
  5. const request = new Request('/api/request', {
  6. method: 'GET',
  7. headers,
  8. });
  9. console.log(request); // Request {method: "GET", url: "http://127.0.0.1:4000/api/request", headers: Headers, destination: "", referrer: "about:client", …}
  10. console.log(request.method); // GET
  11. console.log(request.mode); // cors
  12. console.log(request.credentials); // same-origin
  13. // 如果你想打印headers信息,可以调用 printHeaders(request.headers)

这里我们先以 GET 简单请求作为示例,我们传递了一个自定义的 Headers,指定了请求方法 methodGET(默认为 GET)。在上面的接口规范中,我们可以通过 Request 对象拿到一些常用的属性,比如 methodurlheadersbody 等等只读属性。