動態

詳情 返回 返回

記錄Ajax請求報415與404問題 - 動態 詳情

問題描述與分析

今天幫同學旁邊同事解決了一個問題,問題是這樣的:我們有一個前後端未分離的項目agentBuyFreemark+JQuery),同事想本地啓動agentBuy MVC服務(http:localhost:8001),聯調後端同事的本地啓動的web-inquiry服務(http://127.168.24.68:9366),直接聯調會有跨域問題,於是同事本地啓動網關服務webagentagentBuyweb-inquiry服務代理到http:webagent.java.com:10000域名下聯調,但是發現接口報了415

// agentBuy  
var params = {
  "storeId":"HL000001",
  "quoteType":"AUTO",
  "enable":"Y"
};
$.ajax({
  url: WEB_ROOT + '/inquiryWeb/supply/quote/enable', // 在本地為http:webagent.java.com:10000/inquiryWeb/supply/quote/enable
  type: 'post',
  data : params,
  dataType: 'json',
  success: function (response) {
    // code...
  }
})

發現請求的入參會轉化成鍵值對的形式,Request Payload

storeId=HL000001&quoteType=AUTO&enable=Y

響應狀態碼為415(Unsupported Media Type),表示服務器無法處理請求附帶的媒體格式 (不支持的媒體類型)

@Log4j2
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SupplyQuotationConfigController {

  private final SupplyQuotationConfigClient supplyQuotationConfigClient;

  private static final String REQUEST_NOT_VALIDATE = "請求參數校驗不通過~";
  private static final String INTERNAL_SERVER_ERROR = "網絡異常,請稍後重試~";

  @PostMapping("/supply/quote/enable")
  public ResponseEntity<Result<Boolean>> setSupplyQuoteEnable(@RequestBody SupplyQuoteEnableRequest request) {
    if (null == request || !request.validate()){
      return new ResponseEntity<>(new Result<>(HttpStatus.BAD_REQUEST.value(), REQUEST_NOT_VALIDATE, Boolean.FALSE), HttpStatus.OK);
    }
    try {
      supplyQuotationConfigClient.setSupplyQuoteEnable(SupplyQuotationConfigFactory.toSupplyQuotationEnableRequest(request));
      return new ResponseEntity<>(new Result<>(HttpStatus.OK.value(), null, Boolean.TRUE), HttpStatus.OK);
    }catch (HttpMessageException e){
      return new ResponseEntity<>(new Result<>(e.getStatusCode(), e.getMessage(), Boolean.FALSE), HttpStatus.OK);
    }catch (Exception e){
      return new ResponseEntity<>(new Result<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), INTERNAL_SERVER_ERROR, Boolean.FALSE), HttpStatus.OK);
    }
  }
}

在排查後端接口發現,請求參數使用了@RequestBody註解,用來接收前端傳遞給後端的json字符串數據,而現在傳的鍵值對的類型,因為如果沒有自行指定request header Content-Type,默認為application/x-www-form-urlencoded,因此前後端定義的參數類型不一致,從而報了415錯誤。

request header中設置Content-Type:application/json就可以解決415問題,但是重新請求卻報了404,我仔仔細細對照了一遍請求路徑,發現並沒有什麼問題,並且使用postman本地調試接口也沒有問題,百思不得其解。

後面發現request header中設置了Content-Type:application/json,但Request Payload還是為鍵值對:

storeId=HL000001&quoteType=AUTO&enable=Y

難道是因為鍵值對參數會追加在URL後面使得請求路徑不對?這是為何會變成鍵值對呢?

因為在沒有 MIME 類型的情況下,或者在某些瀏覽器認為設置的MIME 類型不正確情況下,瀏覽器可能會執行MIME 嗅探,通過查看資源的字節來猜測正確的 MIME 類型。上面我們設置Content-Type:application/jsonapplication/json表示需要傳一個json字符串,但是我們傳的是json數據,瀏覽器認為設置的MIME 類型不正確,將參數判定成了鍵值對形式,因此才導致後續請求報404

我們只需要將入參改成json字符串即可解決該問題:

// agentBuy  
var params = {
  "storeId":"HL000001",
  "quoteType":"AUTO",
  "enable":"Y"
};
$.ajax({
  url: WEB_ROOT + '/inquiryWeb/supply/quote/enable', // 在本地為http:webagent.java.com:10000/inquiryWeb/supply/quote/enable
  type: 'post',
  data : JSON.stringify(params), // 改成json字符串
  dataType: 'json',
  success: function (response) {
    // code...
  }
})

參考:

ajax post請求報錯415或400解決方案

MIME 嗅探

https://developer.mozilla.org...

user avatar simonbaker_5ec61c266b1df 頭像 steven_code 頭像 zhedan_sam_wan9 頭像 tong_6816038415d24 頭像 banshee 頭像 xiangjiaochihuanggua 頭像 zzd41 頭像 youyudeshangpu_cny857 頭像 even_5ac21d3322069 頭像 toopoo 頭像
點贊 10 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.