问题描述
今天遇到个问题,接口报错 CORS error
,HTTP请求方式为DELETE
问题分析
很奇怪,明明通过在Spring中注册CorsFilter允许了跨域访问,而且同页面的其他接口都没跨域问题
先看看后台报错日志
org.springframework.web.HttpMediaTypeNotSupportedException: Content type '' not supported
Content type
类型不支持?再看看方法声明
@RequestMapping(value="/delete-by-townId", method = RequestMethod.DELETE, consumes = MediaType.APPLICATION_JSON_VALUE)
果然,在接口声明中,consumes = MediaType.APPLICATION_JSON_VALUE
限制了请求的Content-Type
必须为application/json
可是扒扒封装的axios,不对啊,明明配置了Content-Type,而且直到发送请求的最后一刻,Content-Type都是有值的
可为什么实际请求却没携带呢?
查查看,遇到该问题的网友还不少,最后查到解决办法1和2,在axios发送请求之前,加上config.data = {unused: 0}
,果然可以了,但是不能只知其然,而不知其所以然
先了解一下请求头中Content-Type是什么作用
明白了,请求头中的Content-Type的作用是告诉服务端请求体的格式。
这样就不难理解了,HTTP的GET、DELETE请求方式,通常都是通过URL传递参数,不会携带请求体,请求体都没有,还要Content-Type做什么,所以在axios框架中,没有请求体的时候,就不会携带Content-Type,如果后端还尝试对Content-Type做校验,就会报错
解决办法
知道原因了,解决就很容易
- 方法一:取消后端接口的Content-Type限制,如果
consumes = MediaType.APPLICATION_JSON_VALUE
是声明在Controller类上,可在接口上增加MediaType.ALL_VALUE
覆盖Controller类的配置
@RequestMapping(value="/delete-by-townId", method = RequestMethod.DELETE, consumes = MediaType.ALL_VALUE)
- 方法二:带上请求体
case MethodType.DELETE.code:
// 随便带上什么,只要不是 undefined 就行
requestConfig.data = {flag: true};
return this.delete(api.url, query, requestConfig).then((res: RestfulResponse) => {
// this.addGmisLog(api.url, "4", res, query);
// if (operationLogInfo.operDesc) {
// fromLogService.addLogInfo(operationLogInfo, api, res);
// }
return Promise.resolve(res);
});
break;
这里用方法二试试效果
成功解决!就是不太理解为什么这个异常在浏览器会展示成CORS error
,误导了我好一阵,总之又是充满收获的一天!