Request Payload 和 Form Data 的區別


概述

我正在開發的項目前端和后端是完全獨立的,通過配置 webpack 的 proxy 將前端請求跨域代理到后台服務。昨天發現,我前端執行 post 請求,后台 springmvc 的 @RequestMapping 接收不到對應的請求參數。開始我以為是我 proxy 配置有問題,導致 post 參數不能傳到后台。然而,並不是這樣…

proxy 配置如下:

前端代碼:

java 后台代碼:

Request Payload VS Form Data

前端請求

我看了前端發起的請求,請求正文並不是我熟悉的 Form Data,而是 Request Payload

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

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 不生效。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM