Problem description and analysis

Today, I helped a colleague next to my classmate to solve a problem. The problem is as follows: We have a project agentBuy ( Freemark+JQuery ) that is not separated from the front and back ends. The colleague wants to start the agentBuy MVC service locally ( http:localhost:8001 ), and jointly adjust the web-inquiry service started locally by the back-end colleague. ( http://127.168.24.68:9366 ), there is a cross-domain problem in direct joint debugging, so my colleague started the gateway service webagent to proxy the agentBuy and web-inquiry services to the http:webagent.java.com:10000 domain name for downlink debugging, but found that the interface reported 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...
  }
})

It is found that the requested participants are converted into key-value pairs, Request Payload :

storeId=HL000001&quoteType=AUTO&enable=Y

The response status code is 415 ( Unsupported Media Type ), indicating that the server cannot process the media format (unsupported media type) that came with the request

@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);
    }
  }
}

In the investigation of the back-end interface, it was found that the request parameter was annotated with @RequestBody to receive the json string data passed from the front-end to the back-end, and the type of the key-value pair being passed now, because if request header Content-Type is not specified by itself, the default is application/x-www-form-urlencoded , so before and after The parameter types defined by the terminal are inconsistent, so an error of 415 is reported.

Setting Content-Type:application/json in request header can solve the problem of 415 , but the re-request is reported as 404 . I carefully checked the request path and found that there is no problem, and there is no problem using the postman local debugging interface. .

Later, it was found that request header was set in Content-Type:application/json , but Request Payload was still a key-value pair:

storeId=HL000001&quoteType=AUTO&enable=Y

Is it because the key-value pair parameter will be appended after URL , making the request path wrong? Why does this become a key-value pair?

Because in the absence of the MIME type, or in some cases where the browser thinks the MIME type is set incorrectly, the browser may perform a MIME sniff, guessing the correct MIME type by looking at the bytes of the resource. Above we set Content-Type:application/json , application/json means that a json string needs to be passed, but we pass json data, the browser thinks that the set MIME type is incorrect, and the parameter is judged as a key-value pair, so the subsequent request reports 404

We only need to change the input parameter to json string to solve the problem:

// 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...
  }
})

refer to:

ajax post request error 415 or 400 solution

MIME sniffing

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Type


记得要微笑
1.9k 声望4.5k 粉丝

知不足而奋进,望远山而前行,卯足劲,不减热爱。