axios傳送post請求,request.getParamter接收不到

瓦力發表於2019-01-19

場景如下:
前端vue使用axios向後臺發了一個Content-type為application/json的post請求,
後臺springmvc介面如下:

@RequestMapping("xxx")
public Result xxx(User user) {
    Result result = Result.getSuccessResult();
    return  result;
}

發現接收不到user的資訊。
改為 request.getParamter 也一樣接收不到。
搜尋一番,從這篇部落格找到了答案
AJAX POST請求中引數以form data和request payload形式在servlet中的獲取方式

jquery在執行post請求時,會設定Content-Type為application/x-www-form-urlencoded,所以伺服器能夠正確解析,而使用原生ajax請求時,如果不顯示的設定Content-Type,那麼預設是text/plain,這時伺服器就不知道怎麼解析資料了,所以才只能通過獲取原始資料流的方式來進行解析請求資料。
HTTP POST表單請求提交時,使用的Content-Type是application/x-www-form-urlencoded,而使用原生AJAX的POST請求如果不指定請求頭RequestHeader,預設使用的Content-Type是text/plain;charset=UTF-8。
由於Tomcat對於Content-Type multipart/form-data(檔案上傳)和application/x-www-form-urlencoded(POST請求)做了“特殊處理”。
伺服器為什麼會對錶單提交和檔案上傳做特殊處理,是因為表單提交資料是名值對的方式,且Content-Type為application/x-www-form-urlencoded,而檔案上傳伺服器需要特殊處理,普通的post請求(Content-Type不是application/x-www-form-urlencoded)資料格式不固定,不一定是名值對的方式,所以伺服器無法知道具體的處理方式,所以只能通過獲取原始資料流的方式來進行解析。

總結為:原生ajax如果不指定Context-type預設使用text/plain;charset=UTF-8,jquery的ajax則是application/x-www-form-urlencoded,而axios底層正是使用了原生的ajax,後端會對非Content-type不為application/x-www-form-urlencoded的請求做特殊處理,由此導致後端request.getParameter()無法接收。


解決方法
1、不使用框架的情況下,使用原始的讀取流的方式:

 private String getRequestPayload(HttpServletRequest req) {
   StringBuildersb = new StringBuilder();
   try(BufferedReaderreader = req.getReader();) {
        char[]buff = new char[1024];
        intlen;
        while((len = reader.read(buff)) != -1) {
                 sb.append(buff,0, len);
        }
   }catch (IOException e) {
        e.printStackTrace();
   }
   returnsb.toString();
 }

2、使用spring框架:
加入@RequestBody註解,如下:

@RequestMapping("xxx")
public Result xxx(@RequestBody User user) {
    Result result = Result.getSuccessResult();
    return  result;
}

相關文章