我使用 iisnode 通过 IIS 在 Windows Server 上托管 NodeJS 应用程序。该应用程序具有 Express 路由,当我通过节点(例如 NPM Start)在服务器上启动该应用程序时,它会毫无问题地执行获取路由。
但是,当通过 IIS 运行时,它的路由会出现 404。它加载主页和运行 Swagger 的页面没有问题...但是执行的任何 Get 路由都会生成 404。IIS_IUSRS 帐户可以完全控制整个应用程序文件夹。我怀疑 web.config 中的某些内容没有正确重写获取路由(我原以为默认情况下会发生这种情况)。
这是我的 web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="iisnode" path="server.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<rule name="LogFile" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^[a-zA-Z0-9_\-]+\.js\.logs\/\d+\.txt$"/>
</rule>
<rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^server.js\/debug[\/]?"/>
</rule>
<rule name="StaticContent">
<action type="Rewrite" url="public{REQUEST_URI}"/>
</rule>
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="server.js"/>
</rule>
</rules>
</rewrite>
<iisnode nodeProcessCommandLine="C:\Program Files\nodejs\node.exe" />
<security>
<requestFiltering>
<hiddenSegments>
<add segment="node_modules" />
</hiddenSegments>
<verbs>
<add verb="GET" allowed="true" />
<add verb="POST" allowed="true" />
<add verb="PUT" allowed="true" />
<add verb="DELETE" allowed="true" />
</verbs>
</requestFiltering>
</security>
</system.webServer>
</configuration>
这是我的 server.js (我尝试过带或不带 3000 的端口(例如 const port = process.env.PORT),但行为没有差异):
// MODULES AND REQUIRES
const express = require("express");
const app = express();
const path = require('path');
const swaggerJsDoc = require("swagger-jsdoc");
const swaggerUi = require("swagger-ui-express");
const objectMapper = require('object-mapper');
const cors = require('cors');
// Require Routes
var api1 = require('./routes/api1.js')
var api2 = require('./routes/api2.js')
// PORTS AND BASIC EXPRESS APP SETTINGS
const port = process.env.PORT || 3000;
// CORS ALLOW ALL. NOTE IP RESTRICTIONS ARE IN PLACE
app.use(cors({
origin: '*'
}));
// ignore request for FavIcon. so there is no error in browser
const ignoreFavicon = (req, res, next) => {
if (req.originalUrl.includes('favicon.ico')) {
res.status(204).end();
}
next();
};
// Configure nonFeature
app.use(ignoreFavicon);
// Root Route - Serve Static File
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '/public/client.html'));
});
// SWAGGER UI CONFIGURATION
// Primary Swagger Options
const options = {
customCss: '.swagger-ui .topbar { display: none } .swagger-ui .scheme-container { display: none }'
};
// Custom Swagger Options: https://swagger.io/specification/#infoObject
const swaggerOptions = {
swaggerDefinition: {
info: {
version: "2.0.0",
title: "My App",
description: "This page lists the available APIs within my app and allows you to test them.",
contact: {
name: "My Name"
},
servers: [{"url":"http://localhost:3000", "description": "Development server"}]
}
},
// ['.routes/*.js'] Location for APIs
apis: ["./routes/*.js"],
};
const swaggerDocs = swaggerJsDoc(swaggerOptions);
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerDocs, options));
// ROUTES
app.use('/api1', api1)
app.use('/api2', api2)
// APP LISTEN WITH SSL/HTTPS
app.listen(port, () => {
console.log(`Server listening on port ${port}`);
});
我已经能够通过运行反向代理并将节点设置为在端口 3000 上运行来解决此问题。对于 SSL 地址,我还需要在节点应用程序中添加证书。