在Azure App Service中用虚拟应用部署多Next.js应用遇404问题求助
问题:Azure App Service虚拟应用下Next.js /auth路径404错误
问题场景
在Azure App Service上托管两个Next.js应用,已配置虚拟应用路径映射:
mysite.azure.net/对应主容器Next.js应用mysite.azure.net/auth对应另一个Next.js应用
根路径应用运行正常,但访问/auth路径时始终返回404错误。两个应用的server.js、web.config配置完全一致,相关配置文件如下:
应用配置文件
server.js
const { createServer } = require("http"); const { parse } = require("url"); const next = require("next"); const dev = process.env.NODE_ENV !== "production"; const app = next({ dev }); const handle = app.getRequestHandler(); const port = process.env.PORT || 3000; app.prepare().then(() => { createServer((req, res) => { const parsedUrl = parse(req.url, true); const { pathname, query } = parsedUrl; if (pathname === "/a") { app.render(req, res, "/a", query); } else if (pathname === "/b") { app.render(req, res, "/b", query); } else { handle(req, res, parsedUrl); } }).listen(port, (err) => { if (err) throw err; console.log("> Ready on http://localhost:", port); }); });
web.config
<?xml version="1.0" encoding="utf-8"?> <!-- This configuration file is required if iisnode is used to run node processes behind IIS or IIS Express. --> <configuration> <location path="." inheritInChildApplications="false"> <system.webServer> <webSocket enabled="false" /> <handlers> <add name="iisnode" path="server.js" verb="*" modules="iisnode"/> </handlers> <rewrite> <rules> <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> <security> <requestFiltering> <hiddenSegments> <remove segment="bin"/> </hiddenSegments> </requestFiltering> </security> <httpErrors existingResponse="PassThrough" /> </system.webServer> </location> </configuration>
两个应用的package.json启动命令均为node server.js。
解决方案
需要修改根应用的web.config实现路由转发,同时调整auth应用的server.js适配子路径解析。
1. 修改根应用的web.config
在<rewrite><rules>节点最顶部添加优先匹配/auth路径的规则,确保请求能转发到对应虚拟应用:
<rule name="AuthAppRouting" stopProcessing="true"> <match url="^auth/(.*)" /> <action type="Rewrite" url="auth/{R:1}" /> </rule>
修改后的完整<rules>节点如下:
<rules> <!-- 优先处理/auth路径请求 --> <rule name="AuthAppRouting" stopProcessing="true"> <match url="^auth/(.*)" /> <action type="Rewrite" url="auth/{R:1}" /> </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>
2. 修改auth应用的server.js
为auth应用配置basePath并调整路径解析逻辑,适配子路径:
const { createServer } = require("http"); const { parse } = require("url"); const next = require("next"); const dev = process.env.NODE_ENV !== "production"; // 设置子路径前缀 const app = next({ dev, basePath: "/auth" }); const handle = app.getRequestHandler(); const port = process.env.PORT || 3000; app.prepare().then(() => { createServer((req, res) => { const parsedUrl = parse(req.url, true); // 移除路径前缀,确保Next.js匹配内部路由 const pathname = parsedUrl.pathname.replace(/^\/auth/, "") || "/"; const { query } = parsedUrl; if (pathname === "/a") { app.render(req, res, "/a", query); } else if (pathname === "/b") { app.render(req, res, "/b", query); } else { handle(req, res, { ...parsedUrl, pathname }); } }).listen(port, (err) => { if (err) throw err; console.log("> Ready on http://localhost:", port); }); });
3. 静态资源适配(可选)
如果auth应用有静态资源,修改其web.config中的StaticContent规则:
<rule name="StaticContent"> <match url="^auth/(.*)" /> <action type="Rewrite" url="public/{R:1}"/> </rule>
内容的提问来源于stack exchange,提问作者lonewolf8101
相关产品推荐
相关产品推荐

