Next.js 14部署IIS后重定向指向localhost而非目标IP求助
问题根源
当IIS作为反向代理将请求转发给本地运行的Next.js服务时,默认不会传递原始请求的Host头,导致Next.js的request.nextUrl使用本地服务的localhost:3000作为Origin,最终重定向目标错误。直接硬编码IP会导致Cookie的Domain与当前访问地址不匹配,触发浏览器安全策略无法存储。
解决方案
方案1:配置IIS传递正确请求头,让Next.js识别反向代理
步骤1:修改web.config
更新iisnode节点配置,开启XFF并传递必要服务器变量,同时补充重写规则的头传递设置:
<configuration> <appSettings> <add key="NODE_TLS_REJECT_UNAUTHORIZED" value="0" /> </appSettings> <system.webServer> <iisnode node_env="production" nodeProcessCountPerApplication="1" maxConcurrentRequestsPerProcess="1024" maxNamedPipeConnectionRetry="100" namedPipeConnectionRetryDelay="250" maxNamedPipeConnectionPoolSize="512" maxNamedPipePooledConnectionAge="30000" asyncCompletionThreadCount="0" initialRequestBufferSize="4096" maxRequestBufferSize="65536" uncFileChangesPollingInterval="5000" gracefulShutdownTimeout="60000" loggingEnabled="true" logDirectory="iisnode" debuggingEnabled="true" debugHeaderEnabled="false" debuggerPortRange="5058-6058" debuggerPathSegment="debug" maxLogFileSizeInKB="128" maxTotalLogFileSizeInKB="1024" maxLogFiles="20" devErrorsEnabled="true" flushResponse="false" enableXFF="true" promoteServerVars="HTTP_HOST,HTTP_X_FORWARDED_FOR,HTTP_X_FORWARDED_PROTO" configOverrides="iisnode.yml" watchedFiles="web.config;*.js" nodeProcessCommandLine=""C:\Program Files\nodejs\node.exe"" interceptor=""%programfiles%\iisnode\interceptor.js"" /> <handlers> <add name="iisnode" path="server.js" verb="*" modules="iisnode" /> </handlers> <rewrite> <rules> <rule name="myapp"> <match url="/*" /> <action type="Rewrite" url="server.js" /> <serverVariables> <set name="HTTP_X_FORWARDED_HOST" value="{HTTP_HOST}" /> <set name="HTTP_X_FORWARDED_PROTO" value="{HTTPS}" /> </serverVariables> </rule> </rules> </rewrite> <directoryBrowse enabled="false" /> </system.webServer> </configuration>
步骤2:修改server.js,配置Next.js信任代理
在创建Next实例时添加trustProxy配置,让Next.js识别反向代理传递的头信息:
const { createServer } = require('http') const { parse } = require('url') const next = require('next') const dev = process.env.NODE_ENV !== 'production' const port = process.env.PORT || 3000; // 信任所有代理,确保Next.js读取反向传递的真实请求头 const app = next({ dev, trustProxy: true }) const handle = app.getRequestHandler() 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}`) }) })
方案2:在API路由中手动构造正确重定向URL
如果方案1无法生效,可直接在POST接口中从请求头获取真实访问地址,构造重定向URL:
export async function POST(request: NextRequest) { const formData = await request.formData(); let formDataObject: { [key: string]: any } = {}; formData.forEach((value, key) => { formDataObject[key] = value; }); try { await setSession(JSON.stringify(formDataObject)); //Sets cookies named session } catch (error) { console.log("xyz: ", error); } // 从请求头获取真实的Host和协议,兜底使用部署的IP端口 const host = request.headers.get('host') || '12.96.0.47:3000'; const protocol = request.headers.get('x-forwarded-proto') || 'http'; return Response.redirect(new URL("/", `${protocol}://${host}`)); }
验证方法
修改完成后重启IIS站点,调用POST接口时打印request.headers,查看host和x-forwarded-proto是否为用户访问的IP+端口,确认request.nextUrl.origin是否匹配预期地址。
内容的提问来源于stack exchange,提问作者Ahmed Riaz
相关产品推荐
相关产品推荐

