You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调试POST请求中的net::ERR_FAILED/415 Unsupported Media Type错误?

解决Vue调用POST API时的415、CORS与OPTIONS请求问题

我来一步步帮你理清这些问题的原因和解决方向:

1. 为什么未设置自定义请求头时只有415错误,没有CORS报错?

当你不手动设置Content-Type时,axios默认会把POST请求的Content-Type设为application/x-www-form-urlencoded,这个请求属于CORS简单请求(满足:请求方法是GET/POST/HEAD、Content-Type是三种允许的简单类型之一、没有自定义请求头)。

对于简单请求,浏览器不会发送OPTIONS预检请求,直接发送POST请求到后端。后端收到请求后,发现Content-Type不符合API要求(Swagger显示需要的是其他格式),所以返回415 Unsupported Media Type错误。而这时候后端返回的响应头里应该已经包含了CORS允许的字段(比如Access-Control-Allow-Origin),所以浏览器不会触发CORS报错。

2. 为什么设置自定义请求头后,axios/fetch会发送OPTIONS而非POST?

当你设置了Content-Type: application/json-patch+json(或application/json),这个请求就不再是简单请求了——因为Content-Type不在简单请求允许的三种类型里。此时浏览器会先发送OPTIONS预检请求,用来询问后端:是否允许来自http://localhost:8081的跨域请求?是否允许使用POST方法?是否允许携带这个自定义的Content-Type头?

如果后端的CORS配置没有正确处理OPTIONS请求(比如返回404状态码,或者响应头里缺少必要的CORS字段),浏览器就会判定预检不通过,直接阻止后续的POST请求,同时抛出CORS错误。

至于Chrome和Vivaldi的显示差异:Chrome准确显示了预检的OPTIONS请求(因为POST根本没被发送出去),而Vivaldi可能把浏览器尝试发送POST但被拦截的过程显示为POST请求失败,本质上都是预检不通过导致的问题。

3. 为什么fetch也出现同样的问题?

这完全排除了axios的问题——不管用axios还是原生fetch,只要触发了非简单请求,都会走同样的CORS预检流程。你测试的两种fetch请求结果也验证了这一点:

  • 不设置正确Content-Type时,属于简单请求,直接发送POST,后端返回415(格式不匹配)
  • 设置正确Content-Type时,触发OPTIONS预检,预检不通过导致请求失败

下一步解决建议

你已经把资料发给后端了,建议和后端同事重点确认这几点:

  • 明确API要求的Content-Type到底是application/json-patch+json还是application/json,Swagger文档的描述要准确
  • 检查后端的CORS配置是否正确处理OPTIONS请求:
    • OPTIONS请求必须返回200或204状态码
    • 响应头必须包含Access-Control-Allow-Origin,要允许你的http://localhost:8081
    • 响应头必须包含Access-Control-Allow-Headers,要包含你使用的Content-Type值
    • 响应头必须包含Access-Control-Allow-Methods,要包含POST方法
  • 可以让后端用Postman或curl手动发送OPTIONS请求到该API端点,检查返回的状态码和响应头是否符合要求
  • 暂时可以先尝试用Content-Type: application/json测试,有些后端对application/json-patch+json的支持需要额外配置,先确认基础JSON格式是否能被API接受

内容的提问来源于stack exchange,提问作者YakovL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:02:53