(轉載)http協議的Request Payload 和 Form Data 的區別

(轉載http://hrps.me/2017/05/22/http-request-payload-vs-form-data/前端

概述

我正在開發的項目前端和後端是徹底獨立的,經過配置 webpack 的 proxy 將前端請求跨域代理到後臺服務。昨天發現,我前端執行 post 請求,後臺 springmvc 的 @RequestMapping 接收不到對應的請求參數。開始我覺得是我 proxy 配置有問題,致使 post 參數不能傳到後臺。然而,並非這樣…java

proxy 配置以下:webpack

前端代碼:ios

java 後臺代碼:git

Request Payload VS Form Data

前端請求

我看了前端發起的請求,請求正文並非我熟悉的 Form Data,而是 Request Payload。如圖注意下面兩個請求的 Content-Type 的區別。github

Request Payload 請求web

Form Data 請求spring

瞭解這兩個的區別以前,咱們先回顧下 HTTP 請求報文格式:json

Request Payload 大概格式以下,請求頭部的 Content-Type: application/json,而且請求正文是一個 json 格式的字符串axios

Form Data 大概格式以下,請求頭部的 Content-Type: application/x-www-form-urlencoded,而且請求正文是相似 get 請求 url 的請求參數

後臺處理

對於 Request Payload 請求, 必須加 @RequestBody 才能將請求正文解析到對應的 bean 中,且只能經過 request.getReader() 來獲取請求正文內容

對於 Form Data 請求,無需任何註解,springmvc 會自動使用 MessageConverter 將請求參數解析到對應的 bean,且經過 request.getParameter(...) 能獲取請求參數



解決方案

綜上,我在前端選擇使用 Form Data 的方式來發起請求,使用 qs 庫將 json 對象轉化爲字符串 (如 {name:'dahuang',age: 11} 轉化爲 name=dahuang&age=11)。
以前我覺得 axios 會自動根據你的請求正文格式來選擇發起 Form Data 仍是 Request Payload 請求,可是執行 delete 操做時,如圖的 Content-Type 倒是 text/plain

因此,經過經過下面的方面來解決

一個奇怪的問題

執行 delete 操做時,我將 axios 添加了 headers,content-type: 'application/x-www-form-unlencoded',請求如圖,可是後臺 springmvc 的 @DeleteMapping 接收不到請求參數,必須使用 @RequestParam String id,才能接收到請求參數。看了這個回答,有人回覆說這個是 tomcat 的問題而非 spring 的問題。

更新,今天遇到了一個問題,忽然個人 @PatchMapping 也不能獲取 form 表單傳遞的參數了。以前是能夠的,而後我 google 搜到了 HttpPutFormContentFilter,而後發現這個 filter 在 WebMvcAutoConfiguration 裏面配置的,而這個配置生效其中有一個條件是 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class),剛好,我前兩天整合前端代碼的時候配置 springMVC 繼承了 WebMvcConfigurationSupport.class 因此致使了該 fliter 不生效。

相關文章
相關標籤/搜索