Request 表示一个请求类,需要通过实例化来生成一个请求对象。通过该对象可以描述一个 HTTP 请求中的请求(一般含有请求头和请求体)。既然是用来描述请求对象,那么该请求对象应该具有修改请求头(Headers)和请求体(Body)的方式。下面我们先来看下规范中 Request 具有哪些接口:
typedef (Request or USVString) RequestInfo;[Constructor(RequestInfo input, optional RequestInit init),Exposed=(Window,Worker)]interface Request {readonly attribute ByteString method;readonly attribute USVString url;[SameObject] readonly attribute Headers headers;readonly attribute RequestDestination destination;readonly attribute USVString referrer;readonly attribute ReferrerPolicy referrerPolicy;readonly attribute RequestMode mode;readonly attribute RequestCredentials credentials;readonly attribute RequestCache cache;readonly attribute RequestRedirect redirect;readonly attribute DOMString integrity;readonly attribute boolean keepalive;readonly attribute boolean isReloadNavigation;readonly attribute boolean isHistoryNavigation;readonly attribute AbortSignal signal;[NewObject] Request clone();};Request includes Body;dictionary RequestInit {ByteString method;HeadersInit headers;BodyInit? body;USVString referrer;ReferrerPolicy referrerPolicy;RequestMode mode;RequestCredentials credentials;RequestCache cache;RequestRedirect redirect;DOMString integrity;boolean keepalive;AbortSignal? signal;any window; // can only be set to null};enum RequestDestination { "", "audio", "audioworklet", "document", "embed", "font", "image", "manifest", "object", "paintworklet", "report", "script", "sharedworker", "style", "track", "video", "worker", "xslt" };enum RequestMode { "navigate", "same-origin", "no-cors", "cors" };enum RequestCredentials { "omit", "same-origin", "include" };enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" };enum RequestRedirect { "follow", "error", "manual" };// 来自 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 Header 中 Access-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
// 客户端const headers = new Headers({'X-Token': 'fe9',});const request = new Request('/api/request', {method: 'GET',headers,});console.log(request); // Request {method: "GET", url: "http://127.0.0.1:4000/api/request", headers: Headers, destination: "", referrer: "about:client", …}console.log(request.method); // GETconsole.log(request.mode); // corsconsole.log(request.credentials); // same-origin// 如果你想打印headers信息,可以调用 printHeaders(request.headers)
这里我们先以 GET 简单请求作为示例,我们传递了一个自定义的 Headers,指定了请求方法 method 为 GET(默认为 GET)。在上面的接口规范中,我们可以通过 Request 对象拿到一些常用的属性,比如 method、url、headers 、body 等等只读属性。
