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

如何在IIS部署Angular+Node.js应用及解决Method Not Allowed问题

问题

我有一个基于Angular 17的项目,原本后端用的是.NET Core,之后添加了Node.js作为后端。项目在本地运行完全正常,但部署到生产环境(IIS)后出现“Method Not Allowed”错误。以下是项目的相关配置代码:

Server.js

const express = require("express");
const multer = require("multer");
const path = require("path");
const cors = require("cors");

const app = express();
const PORT = 4000;

app.use(cors());

const storage = multer.diskStorage({
    destination: function(req, file, cb) {
        cb(null, "../src/assets/Folder/");
    },
    filename: function(req, file, cb) {
        cb(
            null,
            file.fieldname + "-" + Date.now() + path.extname(file.originalname)
        );
    },
});
const fileFilter = (req, file, cb) => {
    // Check if file is an image or video
    if (
        file.mimetype.startsWith("image/") ||
        file.mimetype.startsWith("video/")
    ) {
        cb(null, true);
    } else {
        cb(new Error("Only image and video files are allowed"));
    }
};

const upload = multer({
    storage: storage,
    fileFilter: fileFilter,
    limits: { fileSize: 2000000 },
});

app.post("/upload", upload.single("file"), (req, res) => {
    if (!req.file) {
        return res.status(400).json({ message: "No file uploaded" });
    }
    res.status(200).json({
        message: "File uploaded successfully",
        filename: req.file.filename,
    });
});

app.use("uploads", express.static("uploads"));

// Error handling middleware
app.use((err, req, res, next) => {
    if (err instanceof multer.MulterError) {
        // Multer error occurred (e.g., file size exceeded)
        return res.status(400).json({ message: err.message });
    } else if (err) {
        // Other errors (e.g., unsupported file type)
        return res.status(400).json({ message: err.message });
    }
    next();
});

app.listen(PORT, () => {
    console.log(`Server is running on http://localhost:${PORT}`);
});

proxy.config.json

{
    "/api/**": {
        "target": "http://demo.example.com",
        "secure": false,
        "changeOrigin": true,
        "pathRewrite": {
            "^/api": ""
        }
    }
}

Web.Config

<?xml version="1.0" encoding="utf-8"?>
<configuration>

<system.webServer>
  <rewrite>
    <rules>
 <rule name="Angular Routes" stopProcessing="true">
        <match url=".*" />
        <conditions logicalGrouping="MatchAll">
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
      <add input="{REQUEST_URI}" pattern="^.*/admmmin" negate="true" />
        </conditions>
        <action type="Rewrite" url="/" />
      </rule>

           <rule name="redirect1" stopProcessing="true">
                        <match url="^(.*)Admin" />
                 
                    <conditions logicalGrouping="MatchAny">
                        <add input="{HTTP_HOST}{REQUEST_URI}" pattern="(.*)/admin/(.*)" />
                    </conditions>
                    
                </rule>
    </rules>
  </rewrite>
</system.webServer>

</configuration>

请问该如何修复这个错误?是否可以将项目发布到dist文件夹后作为Angular项目上传部署?


解决方案

一、修复“Method Not Allowed”错误的核心措施

1. 正确在IIS中托管Node.js服务

本地运行时Node.js服务是独立启动的,但部署到IIS后,必须通过IIS Node模块将Node.js服务托管在IIS中,否则IIS只会处理Angular静态文件,无法转发请求到/upload接口,直接返回405错误。

2. 修正路径配置问题

  • 文件存储路径:../src/assets/Folder/是本地开发路径,生产环境中dist目录是编译后的静态资源目录,该路径不存在。需改为绝对路径或相对Node.js服务启动目录的路径,示例:
    destination: function(req, file, cb) {
        // 改为和server.js同层级的uploads文件夹
        cb(null, path.join(__dirname, "uploads"));
    },
    
  • 静态资源托管路径:app.use("uploads", express.static("uploads"))缺少前置斜杠,应改为app.use("/uploads", express.static("uploads")),否则路由匹配会异常。

3. 调整IIS重写规则,排除Node.js接口

当前Web.Config的Angular路由重写规则会把所有非文件/目录的请求都重写到/,包括/upload接口请求,导致Node.js服务无法接收POST请求。需在规则中添加排除项:
修改<conditions>部分:

<conditions logicalGrouping="MatchAll">
  <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
  <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
  <add input="{REQUEST_URI}" pattern="^.*/admmmin" negate="true" />
  <add input="{REQUEST_URI}" pattern="^/upload" negate="true" /> <!-- 新增这条排除规则 -->
</conditions>

4. 替换生产环境的代理配置

proxy.config.json仅适用于Angular CLI本地开发,部署到生产环境后无效。生产环境需二选一:

  • 将Node.js服务和Angular静态文件部署在同一个IIS站点下,通过重写规则转发请求;
  • 在Angular代码中直接使用Node.js服务的完整地址(如http://your-server:4000/upload)发起请求。

二、关于部署方式的说明

可以将Angular项目发布到dist文件夹后上传部署,但需注意:

  1. 单独部署Angular静态文件时,Node.js服务需独立部署(比如通过IIS Node托管,或作为Windows服务运行);
  2. 若要将两者部署在同一个IIS站点下:
    • 将dist文件夹内容与Node.js服务文件(server.js、package.json等)放在同一站点目录;
    • 配置IIS Node的web.config,指定启动文件为server.js,同时保留Angular的路由重写规则;
    • 在生产环境运行npm install --production安装依赖包。

三、额外检查项

  • 确认IIS已安装URL Rewrite和IIS Node模块;
  • 检查生产环境中Node.js服务的端口是否开放、未被占用;
  • 验证文件存储目录的权限,确保IIS进程有读写权限;
  • 查看IIS日志和Node.js服务日志,定位具体请求拦截原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 02:57:18