關於post請求, 可以首先參見: 博客
1 Content-Type對各種請求的影響
(1) get請求:
GET 請求不存在請求實體部分,鍵值對參數放置在 URL 尾部,瀏覽器把form數據轉換成一個字串(name1=value1&name2=value2...),然后把這個字串追加到url后面,用?分割,加載這個新的url。因此請求頭不需要設置 Content-Type 字段
但是, 非 ASCII 碼會自動進行編碼轉換,例如發送請求:www.bilibili.com?hehe=你的我的, 中文部分會被轉換成ASCII編碼
(2) post請求:
1.application/x-www-form-urlencoded:數據被編碼為名稱/值對。這是標准的編碼格式。默認行為。會將表單內的數據轉換拼接成 key-value 對(非 ASCII 碼進行編碼)
2.multipart/form-data(一般用來上傳文件): 數據被編碼為一條消息,頁上的每個控件對應消息中的一個部分, 如果是想要文件的上傳操作, 就必須要使用這個請求頭
3.application/json: 數據被編碼為json格式的字符串, 以json格式的字符串發送給后端
3.text/plain: 數據以純文本形式(text/json/xml/html)進行編碼,其中不含任何控件或格式字符。postman軟件里標的是RAW。(中文不進行編碼)
說明: 其實, 請求頭類型的設定, 就是為了制定一個規范, 然后, 整個領域都按照這個規范進行工作,
不管是哪一種請求頭, 起到的作用就是, 首先將數據處理成與此請求頭對應的數據格式, 然后將數據交送給后端並告訴后端我交付的數據到底是哪一種格式,
最為重要的一點是: 前端發送過來的數據, 一定要按照請求頭中的數據對請求數據進行編碼, 否則, 后端是無法正確獲取到請求數據的, 這也是之前一直搞不明白問題所在的主要原因
真正處理數據的, 其實是后端, 后端需要識別請求頭的類型(即請求數據的類型), 然后根據不同的類型解析不同的數據, 這才是最主要的,
不過, 現在的一些框架, 好像都已經封裝好了對請求頭的識別, 我們只需要按照具體的使用方法就可以直接獲取需要前端傳送過來的請求內容
2 springboot中對各種不同請求頭的請求中的參數獲取
(1) application/x-www-form-urlencoded: 直接通過RequestParam(value="name")獲取即可
(2) multipart/form-data: 這個也可以直接通過RequestParam(value="name")的形式獲取, 不過, 需要注意的是, 請求的數據, 一定要按照此種類型進行編碼, 下面會具體針對這個東西進行一些問題的解決
(3) application/json: 這個可以通過RequestBody Map<String, Object> map的形式獲取, 不過, 需要注意的, 傳送的數據, 一定要被序列化成json格式, 可以手動序列化( JSON.stringify() ), 也可以借助一些封裝好的框架進行序列化(好像axios就會自動進行一些序列化, 具體還不清楚)
3 幾個注意點:
(1) 如果想要進行文件上傳操作, 就必須要使用multipart/form-data請求頭, 方式有兩種
一種是通過form標簽, 設置enctype="multipart/form-data", 這樣在表單提交的時候, 就會自動將所有的數據編碼成multipart/form-data格式
另一種是構建FormData對象, 然后將FormData對象作為數據傳送給后端, 由於FormData對象默認會使得Content-Type變為multipart/form-data, 所以, 也會自動將數據編碼成multipart/form-data格式
(2) jquery中封裝的ajax請求, 有兩個參數需要特別注意
processData: 這個參數是jquery中特有的, 默認情況下, 會將數據處理成application/x-www-form-urlencoded格式, 所以, 如果我們進行文件上傳操作時(即需要設置請求頭為multipart/form-data時), 需要將屬性值設置為false, 即禁用這個選項
contentType: 這個參數是用來設置請求頭的, 也可以在header:{...}屬性中進行設置, 同樣, 如果我們是想要進行文件上傳操作, 也需要將這個屬性設置為false, 即禁用這個屬性, 因為, 它的屬性值默認為application/x-www-form-urlencoded, 那, 為什么不將其設置為multipart/form-data呢? 因為, 對於multipart/form-data格式, 請求頭需要有兩個屬性, 即除了設置multipart/form-data, 還需要附加一個屬性boundary=---fjdkgjgdjakdjgjdgajl, 但是這個值一般都是由瀏覽器隨機生成並指定的, 無法手動定義(如果手動定義的話會出錯), 所以, 就需要禁用contentType屬性了, 禁用之后, 會使用FormData對象中的post方式作為contentType, 即是multipart/form-data嘍, 並且瀏覽器還會自動生成boundary, 不是很好嗎.