Photo by Luca Bravo on Unsplash
GET還是POST?
· 考慮將瀏覽器作為客戶端,可以緩存哪種方法?
· 哪個是"安全"方法?
· 哪一個不是冪等的?
· 如果我將端點URL復制并粘貼到瀏覽器的地址欄中,然后按Enter,默認情況下會調用哪種方法?
· 哪個方法請求有正文?
· 考慮到靜態網站,此應用程序響應的唯一方法是什么?
· 哪種方法有長度限制?
· 哪種方法更安全,應該用于處理敏感數據?
· 哪種方法可以加書簽?
· 哪種方法僅允許使用ASCII字符?
您知道所有答案嗎,為什么? 如果您不這樣做,就沒有理由感到羞恥。 讓我們更詳細地分析這兩種方法并了解它們的特殊性。
- GET參數將存儲在瀏覽器的會話歷史記錄中。
瀏覽器使用其歷史記錄來前后導航用戶,因此,輸入的每個新URL都會自動進入歷史記錄。 但是,如果通過SPA隱式完成GET請求(通過ajax或axIOS)怎么辦? 在這種情況下,必須通過history.pushState手動推送請求URL,并且可以在瀏覽器的URL地址上更新請求URL,而無需重定向用戶。
考慮兩種不同的情況:
A.轉到 該網站將發出一個新的GET請求,獲取響應,重新呈現產品列表,更新瀏覽器URL地址并將該URL保存在瀏覽器歷史記錄中(不一定按此順序)。 盡管頁面沒有刷新,但是新查詢仍被推送到瀏覽器歷史記錄,因此您將能夠導航回到初始頁面。
Image form kogan
選擇免費送貨時:
Image form kogan
請注意,在不刷新頁面的情況下發出了新請求,現在啟用了后退按鈕,并且瀏覽器中設置的URL與檢查中的URL甚至有所不同。
B.現在轉到 該網站將發出新的GET請求,獲取響應,重新呈現產品列表并更新瀏覽器URL地址。 但是,它不會將網址保存在瀏覽器歷史記錄中。 盡管未刷新頁面,但由于新查詢未推送到瀏覽器歷史記錄,因此您將無法導航回初始頁面。
Image form kogan
請注意,在不刷新頁面的情況下發出了新請求,即使在瀏覽器URL更改后,后退按鈕仍未啟用。
關于POST,如果用戶在提交表單后返回導航,則數據將被重新提交(瀏覽器應警告用戶該數據將被重新提交),但不會保留在歷史。
Chrome form resubmission popup
2. GET響應可以被緩存
由于GET是冪等的,并且大多數網頁資源都是通過此方法返回的,因此默認情況下,瀏覽器將緩存get請求。 因此,下次訪問該網頁時,無需訪問服務器并再次請求所有圖像,而只需從瀏覽器的緩存中加載即可。
在REST API的上下文中,發出多個相同的請求與發出單個請求具有相同的效果-則該REST API被稱為等冪。
這樣做的好處是,您的網站在第一次加載后將加載得更快。 但是,如果新的部署將舊的網站緩存在其瀏覽器中,則無法到達客戶端。 結果,為了使緩存無效,每個請求的URL必須更改,或者客戶端必須在其瀏覽器上執行。 例如,如果您網站的css由URL cdn-static-1.medium.com//fp/css/main-branding-base.-y85vioUz7M8dDBgC99oNg.css表示,則新的部署只會更改 如果將該網址更改為cdn-static-1.medium.com//fp/css/main-branding-base.newhashkey.css之類的網站。
Medium home page network. Highlight on CSS file.
POST不能在客戶端緩存。POST不是冪等(4)。
3.GET是一種安全的方法
因為此方法永遠都不應更改資源(如果您沒有實現RESTful最佳實踐),則認為它是安全的。
安全方法是不修改資源的HTTP方法。
因此,可以安全地對其進行緩存,保存在瀏覽器的歷史記錄中以及保存在搜索引擎(例如google)中。 這是因為參數將存儲在URL中,并且調用該方法不會對服務器造成任何更改。 另一方面,POST不是安全的方法。
4.靜態網站僅響應GET請求
靜態網站是一種不需要任何其他工具來處理其文件的應用程序,因為它們將返回瀏覽器可讀的內容(JAVAScript,圖像,CSS,html)。 因此,它只需要響應GET請求即可返回html頁面。 那么,這些信息的含義是什么?
您是否知道僅使用AWS S3即可托管靜態網站? 我相信很多人會說"是"。 但是還知道它只允許GET和HEAD請求嗎? 根據他們的文檔,在S3存儲桶上請求的所有對象都必須通過GET。
5.哪種方法有長度限制?
理解GET方法將始終轉換為瀏覽器中的URL(http協議)并且僅允許ASCII字符非常重要。 換句話說,您在瀏覽器URL地址中輸入的任何文本都會發出服務器GET請求,即使GET請求是通過網站隱式完成的(例如,通過Ajax),它仍會將其轉換為 URL參數的格式如查詢字符串。
知道瀏覽器上的GET請求將通過URL發送參數,如果過濾器過多,您會怎么辦? 盡管此數字在瀏覽器之間可能略有不同,但是安全的URL長度限制通常為2048個字符,減去實際路徑中的字符數。 因此,如果您要建立一個網站,在該網站中您的產品可以具有各種各樣的篩選器,則GET方法可能不夠。
關于POST,由于有效負載是在請求的正文中發送的,因此從技術上講,發送的數據沒有限制數據類型也沒有限制。
6.哪種方法更安全,應該用于處理敏感數據?
盡管許多人正確地做到這一點,但他們通常不知道為什么。 考慮到基本的用戶密碼登錄端點,您是否想知道為什么將其用于POST而不是GET? 是的,它與安全有關,但不是因為信息被隱藏。 它與我們在這里討論的第一點有關:瀏覽器緩存和歷史記錄。
想象一下,如果您開始在瀏覽器中鍵入網站,它會自動在查詢字符串中建議一個包含用戶名和密碼的URL。 聽起來可能很奇怪,但是GET登錄端點將允許這樣做,我確定那不是您想要的。
Browser suggesting URLs from history
7.哪種方法可以加書簽?
POST不應添加書簽,其原因是上述幾個主題的組合:
· 嘗試為POST添加書簽只會對URL進行GET操作。
· 該方法不是冪等的,因此不能保證響應將始終相同。 例如,這可能導致銀行交易重復。
· 由于書簽不支持正文有效負載,因此該網址將丟失其參數。
· 它可能包含敏感數據,不應存儲。
結論
盡管通常使用GET來獲取數據并使用POST來發送/保存數據,但我們可以得出結論,這兩種方法還有很多,并且意識到這些特性將不僅有助于編寫更好的代碼,還有助于架構,設計和解決問題。 那么,您的分數如何?
資源資源
(本文翻譯自Cbernades的文章《11 things you should know about GET vs POST》,參考:https://medium.com/JavaScript-in-plain-english/get-vs-post-are-you-confident-about-the-differences-189562fac0a7)