PWA(Progressive Web App)入门系列:Fetch Request Headers Response Body
前言
在 WEB 中,對于網絡請求一直使用的是 XMLHttpRequest API 來處理,XMLHttpRequest 也很強大,傳統的 Ajax 也是基于此 API 的。那么為什么 W3C 標準中又加入了類似功能的 Fetch API 呢?他有何優勢。
Fetch
什么是 Fetch
Fetch 提供了 Request 和 Response 對象的通用定義(以及與網絡請求有關的其他內容)。這將允許 Fetch 在將來需要的任何地方使用,無論在 serviceWorker、Cache API以及處理或修改 Request 和 Response 的其他類似事物上,或者任何可能需要你以編程方式生成的 Response 的地方。
它還提供了相關概念的定義,例如 CORS 和 HTTP 原始頭語義,在其他地方取代它們的單獨定義。
要發出請求并獲取資源,請使用 WindowOrWorkerGlobalScope.fetch() 方法。這使得它幾乎可以在你想要獲取資源的任何上下文中使用。
Fetch API 是 W3C 正式規范中加入的新的用于網絡請求相關的功能 API,核心就是對于 HTTP 接口的抽象,包含 Request / Response / Headers / Body,通過這些抽象出來的模塊,對于 HTTP 相關的操作變得更簡單方便。Fetch API 是異步化的接口,所有的結果都是 Promise 化的,同樣在 window 環境和 seviceWorker 環境下均可訪問。在 ServiceWorker 中,Fetch 被大量使用。
對于使用過 XMLHttpRequest 的人來說,很容易上手。但 Fetch API 功能更強大和靈活。
模塊與 fetch 的關系
接口
描述 Fetch 的接口,不是很單純,它是以抽象出來的 HTTP 的那些模塊來組合的。下面簡單列一下,后面每個模塊詳細說明。
fetch
位于 WindowOrWorkerGlobalScope 這一個 mixin 中的 fetch() 方法用于發起獲取資源的請求。它返回一個 promise,這個 promise 會在請求響應后被 resolve,并傳回 Response 對象。
Window 和 WorkerGlobalScope 下均可訪問 fetch() 方法。
fetch() 方法由 Content Security Policy 的 connect-src指令控制,而不是它請求的資源。
HTTP 404 狀態并不被認為是網絡錯誤。
語法
Promise<Response> fetch(input[, init]);fetch() 的構造器和 Request 的構造器完全一樣。
參數
resource:支持以下兩種類型:
- USVString:要獲取資源的 URL 字符串。(有些瀏覽器也支持 blob:和data:類型的 URL)
- Request 對象。 (Request 這塊在后面 Request 部分說)
init:可選。可設置任何需要應用到 Request 中的配置項。通常設置如下:
- method:請求的方法。如 POST、GET等。注意在 Fetch 請求方法為 GET 或 HEAD 下不能設置 Origin 頭。(Firefox 65 已修正此問題 - 參考:Bug1508661)
- headers:在 Headers 對象或具有 ByteString 值的對象中的任何你想添加的頭。注意某此名稱是被禁止的。
- body:任何你想添加到 Request 中的 body,它可以是 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 對象。注意 GET 或者 HEAD 方法的 Request 沒有 body。
- mode:用于請求的模式。例如:cors, no-cors, 或者 same-origin。
- same-origin:如果設置了此模式,并向其他源發請求,則報錯。此屬性可強制始終從同一個源發請求。
- no-cors:保證其對應的方法只有HEAD,GET或POST方法。serviceWorker 攔截的請求只能添加或修改一些簡單的 header,且 JS 無法讀取 Response 的任何屬性。保證在跨域時不會發生安全和隱私泄露的問題。
- cors:允許跨域請求。只有有限的 header 暴露在 Response 中,正文可以讀取。
- navigate:瀏覽器的頁面切換請求。navigate 請求僅在瀏覽器切換頁面時創建,該請求應該返回 HTML。
- credentials:用于請求的受信類型,包括:omit, same-origin, 或者 include。要自動發送當前域的cookie,必須提供此選項。從Chrome 50開始,此屬性還會使用FederatedCredential實例或PasswordCredential實例。
- omit:不發送 cookies。
- same-origin:同源環境下發送 cookies。
- include: 任何情況都發送 cookies。
- cache:要用于請求的緩存模式。
- default:默認,走 HTTP 緩存模式。
- reload:瀏覽器先從服務器獲取資源,而不是先查找緩存,資源下載完后更新緩存。
- no-store:瀏覽器從服務器獲取資源,且不更新緩存。
- no-cache:瀏覽器在HTTP緩存中查找匹配的請求。如果有新的或舊的匹配,瀏覽器將向遠程服務器發出有條件的請求。如果服務器指示資源沒有改變,它將從緩存中返回。否則,資源將從服務器下載,緩存將被更新。
- force-cache:基于 HTTP 緩存。
- only-if-cached:只走 HTTP 緩存,如果沒有則報錯。
- redirect:要使用的重定向模式:follow(自動跟隨重定向),error(如果發生重定向則中止錯誤),manual(手動處理重定向)。Chrome 默認follow(Chrome 47 以前默認 manual)。
- referrer:指定no-referrer,client或URL的USVString。默認為client。
- referrerPolicy:指定 referer HTTP 標頭的值。 可以是 no-referrer, no-referrer-when-downgrade, origin, origin-when-cross-origin, unsafe-url。
- integrity:包含請求的子資源完整性值(例如:sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=)。
- keepalive:keepalive選項可用于允許請求比頁面長。帶keepalive標志的 fetch 替代了navigator.sendboacon() API。
- signal:AbortSignal實例。允許你與獲取請求進行通信,并在需要時通過AbortController中止它。
返回值
Promise,resolve 時回傳 Response 對象。
例外
| AbortError | 請求中斷 (通過使用 AbortController.abort()) |
| TypeError | 從Firefox 43開始,如果 URL 包含 credentials ,則 fetch() 將拋出 TypeError,例如 http:// user:password@example.com。 |
Request
Fetch API 的 Request 接口表示資源請求。
你可以使用 Request.Request() 構造函數創建新的 Request 對象,你也可以通過一個 API 操作返回 Request 對象,例如 serviceWorker 中的 FetchEvent.request。
構造器
Request.Request()
創建新的 Request 對象。
語法
var myRequest = new Request(input[, init]);參數
input: 可用如下之一:
- 要獲取資源的 URL 字符串。
- Request 對象,用于創建副本。請注意以下行為更新以保持安全性,同時使構造函數不太可能拋出異常:
- 如果此對象存在于構造函數調用的另一個源上,則會剝離 Request.referrer。
- 如果此對象具有navigate的 Request.mode,則mode值將轉換為same-origin。
init: 可選。同 fetch init。
屬性
- cache:包含請求的緩存模式,例如:default, reload, no-cache。
- credentials:包含請求的憑據,例如:omit, same-origin, include。默認same-origin。
- destination:返回RequestDestination枚舉中的字符串,描述請求的目標。這是一個字符串,表示所請求內容的類型。
- headers:包含請求的關聯 Headers 對象。
- integrity:包含請求的子資源完整性值。例如:sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=。
- method:包含請求的方法,GET/POST等。
- mode:包含請求的模式。例如:cors, no-cors, same-origin, navigate。
- redirect:包含重定向處理方式。它可能是其中之一:follow, error, manual。
- referrer:包含請求的引用者。例如:client。
- referrerPolicy:包含請求的引用者策略。例如:no-referrer。
- url:包含請求中的 URL。
- bodyUsed :存儲一個布爾值,聲明是否已在響應中使用過。
Request 實現 Body,所以 Body 的屬性和方法在 Request 中依然有效。關于 Body,后面說。
Headers
Fetch API 的 Headers 接口允許你對 HTTP 請求和響應頭執行各種操作。這些操作包括檢索,設置,添加和刪除。Headers 對象具有關聯的標題列表,該列表最初為空,由零個或多個名稱和值對組成。在此接口的所有方法中,標頭名稱由不區分大小寫的字節序列匹配。
出于安全原因,某些標頭只能由瀏覽器控制。這些標頭包括禁止的標頭名稱和禁止的響應標頭名稱。
一個Headers對象也有一個相關的“門”,取值為immutable, request, request-no-cors, response, none。它會影響 set(), delete(), append() 是否會改變 header。
你也可以通過 Request.headers 和 Response.headers 屬性取 Headers 對象。
構造器
Headers
創建一個 Header 對象。
語法:
var myHeaders = new Headers(init);參數:
- init:包含要使用其預填充 Headers 對象的任何HTTP標頭的對象。這可以是具有 ByteString 值的簡單對象值或現有的 Headers 對象(新的 Headers 對象從現有的Headers對象繼承其數據)。
方法
- append(name, value):將新值附加到 Headers 對象內的現有標頭上,或者如果標頭、不存在則添加標頭。此方法用于一個屬性對應多個值的添加方法。
- delete(name):方法從當前 Headers 對象中刪除指定標頭。
- entries():方法返回一個迭代器,允許遍歷此對象中包含的所有鍵/值對。每對的鍵和值都是 ByteString 對象。
- forEach():為每個數組元素執行一次提供的函數。
- get(name):方法返回具有給定名稱的 Headers 對象中標頭的所有值的字節字符串。如果 Headers 對象中不存在請求的標頭,則返回 null。
- has(name):方法返回一個布爾值,表明Headers對象是否包含某個頭。
- keys():方法返回一個迭代器,允許遍歷此對象中包含的所有鍵。鍵是 ByteString 對象。
- set(name, value):方法為 Headers 對象內的現有標頭設置新值,或者如果標頭尚不存在則添加標頭。(set 和 append 之間的區別在于,如果指定的頭已經存在并接受多個值,則 set 將使用新值覆蓋現有值,而 append將新值附加到值集的末尾)
- values():返回一個迭代器,允許遍歷此對象中包含的所有值。值是 ByteString 對象。
如果在 Header 中的方法中使用不在可用 HTTP 標頭中的值,則會拋出 TypeError 錯誤。
可用 HTTP 表頭
表頭根據上下文有如下幾類:
- 常規標題:標題適用于請求和響應,但與最終在正文中傳輸的數據無關。
- 請求標頭:包含有關要提取的資源或客戶端本身的更多信息的標頭。
- 響應標頭:包含有關響應的其他信息的標頭,例如其位置或服務器本身(名稱和版本等)。
- 實體標頭:包含有關實體主體的更多信息的標頭,例如其內容長度或MIME類型。
認證類:
- WWW-Authenticate
- Authorization
- Proxy-Authenticate
- Proxy-Authorization
緩存類:
- Age
- Cache-Control
- Clear-Site-Data
- Expires
- Pragma
- Warning
客戶端提示類:
- Accept-CH
- Accept-CH-Lifetime
- Early-Data
- Content-DPR
- DPR
- Save-Data
- Viewport-Width
- Width
條件類:
- Last-Modified
- ETag
- If-Match
- If-None-Match
- If-Modified-Since
- If-Unmodified-Since
- Vary
連接管理類:
- Connection
- Keep-Alive
內容判斷類:
- Accept
- Accept-Charset
- Accept-Encoding
- Accept-Language
控制類:
- Expect
- Max-Forwards
Cookie 類:
- Cookie
- Set-Cookie
CORS 類:
- Access-Control-Allow-Origin
- Access-Control-Allow-Credentials
- Access-Control-Allow-Headers
- Access-Control-Allow-Methods
- Access-Control-Expose-Headers
- Access-Control-Max-Age
- Access-Control-Request-Headers
- Access-Control-Request-Method
- Origin
- Timing-Allow-Origin
- X-Permitted-Cross-Domain-Policies
不追蹤類:
- DNT
- TK
下載類:
- Content-Disposition
消息正文類:
- Content-Length
- Content-Type
- Content-Encoding
- Content-Language
- Content-Location
代理類:
- Forwarded
- X-Forwarded-For
- X-Forwarded-Host
- X-Forwarded-Proto
- Via
重定向類:
- Location
請求上下文類:
- From
- Host
- Referer
- Referrer-Policy
- User-Agent
響應上下文類:
- Allow
- Server
范圍請求類:
- Accept-Ranges
- Range
- If-Range
- Content-Range
安全類:
- Cross-Origin-Resource-Policy
- Content-Security-Policy
- Content-Security-Policy-Report-Only
- Expect-CT
- Feature-Policy
- Public-Key-Pins
- Public-Key-Pins-Report-Only
- Strict-Transport-Security
- Upgrade-Insecure-Requests
- X-Content-Type-Options
- X-Download-Options
- X-Frame-Options
- X-Powered-By
- X-XSS-Protection
服務器發送事件類:
- Last-Event-ID
- NEL
- Ping-From
- Ping-To
- Report-To
轉移編碼類:
- Transfer-Encoding
- TE
- Trailer
WebSockets 類:
- Sec-WebSocket-Key
- Sec-WebSocket-Extensions
- Sec-WebSocket-Accept
- Sec-WebSocket-Protocol
- Sec-WebSocket-Version
其他:
- Accept-Push-Policy
- Accept-Signature
- Alt-Svc
- Date
- Large-Allocation
- Link
- Push-Policy
- Retry-After
- Signature
- Signed-Headers
- Server-Timing
- SourceMap
- Upgrade
- X-DNS-Prefetch-Control
- X-Firefox-Spdy
- X-Pingback
- X-Requested-With
- X-Robots-Tag
- X-UA-Compatible
Response
Response 接口表示請求的響應。
構造器
Response()
語法:
var myResponse = new Response(body, init);參數:
body:(可選)
定義響應主體的對象。這可以是null,或者是:
- Blob
- BufferSource
- FormData
- ReadableStream
- URLSearchParams
- USVString
init:(可選)
包含要應用于響應的任何自定義設置的選項對象。可選:
- status:響應的狀態代碼,例如:200。
- statusText:與狀態代碼關聯的狀態消息,例如,OK。
- headers:要添加到響應的任何標頭,包含在 Headers 對象或 ByteString 鍵/值對的對象文本。(可參考 HTTP Headers)
屬性
- headers:接口的頭只讀屬性包含與響應關聯的 Headers 對象。
- ok:接口的 ok 只讀屬性包含一個布爾值,表明響應是否成功(狀態在200-299范圍內)
- redirected :屬性指示響應是否是您重定向的請求的結果。依靠 redirected 來過濾掉重定向,可以輕松進行偽造重定向,以防止你的內容按預期工作。相反,你應該在調用 fetch() 時執行過濾。
- status:響應的狀態代碼。
- statusText:相應狀態文字。
- type:響應類型:
- basic:正常情況下同域響應,除Set-Cookie和Set-Cookie2外,所有標題都被暴露。
- cors:從有效的跨源請求收到響應。
- error:網絡錯誤。 沒有描述錯誤的有用信息。響應的狀態為 0,標頭為空且不可變。 這是從Response.error()獲取的響應的類型。
- opaque:響應“no-cors”請求到跨源資源。
- opaqueredirect:獲取請求是使用重定向manual進行的。 響應的狀態為 0,標題為空,正文為空。
- url:包含響應的 URL。 url 屬性的值將是重定向后獲得的最終 URL。
- bodyUsed :布爾值,聲明是否已在響應中使用了正文。
方法
- clone():方法創建響應對象的克隆,在各方面都相同,但存儲在不同的變量中。
- error():方法返回與網絡錯誤關聯的新Response對象。
- redirect(url, status):方法返回一個 Response,導致重定向到指定的 URL。
Request 實現 Body,所以 Body 的屬性和方法在 Request 中依然有效。關于 Body,后面說。
Body
Body 表示響應 / 請求的主體,允許你聲明其內容類型以及應如何處理它。
Body 由 Request 和 Response 實現。這為這些對象提供了關聯的主體(流),使用過的標志(最初未設置)和MIME類型(最初是空字節序列)。
屬性
- body:是一個簡單的getter,用于公開body內容的ReadableStream。
- bodyUsed:布爾值,指示是否已讀取 body。
方法
- arrayBuffer():方法接受一個 Response 流并將其讀取完成。它返回一個使用 ArrayBuffer 解析的 promise。
- blob():方法接受一個 Response 流并將其讀取完成。它返回一個用 Blob 解析的 promise。(注意 如果 Response 的 Response.type 為opaque,則生成的 Blob 將具有 0 的 Blob.size 和空字符串“”的 Blob.type,這使得它對 URL.createObjectURL 等方法無效。)
- formData():方法接受一個 Response 流并將其讀取完成。它返回一個使用 FormData 對象解析的 promise。(這主要與 serviceWorker 有關。 如果用戶提交表單并且 serviceWorker 截獲請求,你可以在其上調用 formData() 以獲取鍵值映射,修改某些字段,然后將表單向前發送到服務器)
- json():方法接受一個 Response 流并將其讀取完成。它返回一個 promise,它以將正文解析為 JSON 的結果解析。
- text(): 方法接受一個 Response 流并將其讀取完成。 它返回一個使用 USVString 對象(文本)解析的 promise。 始終使用 UTF-8 解碼響應。
瀏覽器兼容性
博客名稱:王樂平博客
CSDN博客地址:http://blog.csdn.net/lecepin
本作品采用知識共享署名-非商業性使用-禁止演繹 4.0 國際許可協議進行許可。總結
以上是生活随笔為你收集整理的PWA(Progressive Web App)入门系列:Fetch Request Headers Response Body的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 沉浮二十载,奥飞成也萧何败也萧何?
- 下一篇: 代码的坏味道之一——译自《重构》