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

Node.js中Axios POST请求报405 Method Not Allowed错误如何解决?

问题根因

返回405状态码的核心原因是浏览器发送multipart/form-data类型的非简单POST请求前,会自动发起OPTIONS方法的CORS预检请求,你的服务端只注册了POST /images路由,没有对OPTIONS请求做响应处理,预检阶段直接被拦截返回405,真正的POST请求根本不会发出。
Postman不会触发浏览器的CORS预检逻辑,所以可以直接调通接口。

现有代码还存在两个会导致请求失败的隐藏问题:

  • 已经全局注册了cors中间件,又在单个POST路由里重复手写CORS响应头,属于冗余配置,且手动配置的头不全,没有放行文件上传需要的相关请求头
  • 前端手动给FormData请求设置Content-Type: multipart/form-data,会覆盖Axios自动生成的boundary边界参数,导致后端multer中间件无法正确解析上传的文件

修复步骤

1. 修正服务端CORS配置,放行OPTIONS预检请求

删除路由内重复手写的CORS响应头代码,补全全局cors配置,单独处理所有OPTIONS预检请求,修改后的服务端代码如下:

var cors = require("cors");
var serveStatic = require('serve-static');
const path = require('path');
// 全局配置cors,无需在单个路由中重复设置响应头
app.use(cors({
  origin: "*",
  methods: ["GET", "POST", "OPTIONS", "PUT", "PATCH", "DELETE"],
  allowedHeaders: ["X-Requested-With", "Content-Type", "Content-Disposition"],
  credentials: false
}));

// 统一拦截所有OPTIONS请求,返回204状态码通过预检
app.options("/*", (req, res) => {
  res.sendStatus(204);
});

const client = new vision.ImageAnnotatorClient(config, clientOptions);

// 简化POST路由,移除冗余的CORS头设置代码
app.post("/images", upload.single("file"), function (req, res, next) {
  client
    .textDetection(req.file.path)
    .then((results) => {
      res.send(results);
    })
    .catch((err) => {
      res.status(400).send(err);
    });
});

app.use(serveStatic(path.join(__dirname, "public")));
const server = app.listen(port);
console.log(`${pjson.name} running => port ${server.address().port}`);

2. 修正前端Axios请求配置

不要手动给FormData类型的请求设置Content-Type头,让Axios自动识别FormData格式并生成带正确boundary边界的请求头,同时增加空文件校验,修改后的前端代码如下:

<form role="form" class="form" onsubmit="return false;">
     <div class="form-group">
         <label for="file">File</label>
         <input id="file" type="file" class="form-control" accept=".JPG,.jpg,.jpeg,.gif,.png" />
     </div>
     <button id="text_detect" type="button" class="btn btn-primary">
         Get Text
     </button>
 </form>

<script>
document.getElementById('text_detect').onclick = function () {
  output.innerHTML = '';
  const fileInput = document.getElementById('file');
  if (!fileInput.files[0]) {
    alert('请先选择要上传的图片');
    return;
  }
  const data = new FormData();
  data.append('file', fileInput.files[0]);
  // 移除手动设置的Content-Type头,由Axios自动生成
  axios.post('/images', data)
    .then(function (result) {
      const properties = result.data[0].fullTextAnnotation; 
      console.log(properties); 
    })
    .catch(function (err) {
      console.log(err);
    })
}
</script>

验证方式

修改完成后重启Node服务,打开浏览器控制台网络面板,可以看到先发起了一个状态码为204的OPTIONS请求到/images路径,预检通过后才会发送真正的POST上传请求,接口即可正常返回识别结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 18:39:18