记录Ajax请求报415与404问题
问题描述与分析
今天帮同学旁边同事解决了一个问题,问题是这样的:我们有一个前后端未分离的项目agentBuy
(Freemark+JQuery
),同事想本地启动agentBuy
服务(http:localhost:8001
),联调后端同事的本地web-inquiry
服务(http://127.168.24.68:9366
),直接联调会有跨域问题,于是同事本地启动网关服务(spring cloud gateway
)将agentBuy
、web-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"eType=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> 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"eType=AUTO&enable=Y
难道是因为键值对参数会追加在
URL
后面使得请求路径不对?这是为何会变成键值对呢?因为在没有
MIME
类型的情况下,或者在某些浏览器认为设置的MIME
类型不正确情况下,浏览器可能会执行MIME
嗅探,通过查看资源的字节来猜测正确的 MIME
类型。上面我们设置Content-Type:application/json
,application/json
表示需要传一个json
字符串,但是我们传的是json
数据,浏览器认为设置的MIME
类型不正确,将参数判定成了键值对形式,因此才导致后续请求报404
。【记录Ajax请求报415与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...
推荐阅读
- 20170612时间和注意力开销记录
- 【剽悍读书营成长记录】2018年我收获了什么|【剽悍读书营成长记录】2018年我收获了什么 3357-小松
- 记录iOS生成分享图片的一些问题,根据UIView生成固定尺寸的分享图片
- https请求被提早撤回
- 课后分享记录
- 遇到不正当请求怎么办
- 感赏15+投射
- Day5+5组+小鹿#写手账,就是记录你一生的帐
- 不知不觉,他们又长大了一点
- 使用Promise对微信小程序wx.request请求方法进行封装