Next.js自定义服务器部署IIS,HTTPS重定向中间件引发循环重定向故障
解决Next.js自定义服务器部署IIS的HTTPS循环重定向问题
问题根源分析
- IIS反向代理未正确传递HTTPS标识头,导致中间件始终判定请求为HTTP,持续触发重定向
- 原中间件的URL构造逻辑存在漏洞,易生成错误地址
- 自定义服务器与IIS的重定向规则冲突,引发循环
具体解决方案
1. 修正中间件逻辑
替换原中间件代码,优化HTTPS判断逻辑,兼容IIS特有的请求头:
import { NextRequest, NextResponse } from 'next/server' type Environment = "production" | "development" | "other"; export function middleware(request: NextRequest) { const currentEnv = process.env.NODE_ENV as Environment; // 优先识别IIS的X-ARR-SSL头,同时兼容通用的X-Forwarded-Proto const isHttps = request.headers.get("X-ARR-SSL") !== undefined || request.headers.get("x-forwarded-proto")?.toLowerCase() === "https"; const isLocalhost = request.headers.get("host")?.includes("localhost"); if (currentEnv === "production" && !isHttps && !isLocalhost) { // 基于原请求URL直接修改协议,避免拼接错误 const newUrl = new URL(request.url); newUrl.protocol = "https:"; return NextResponse.redirect(newUrl, 301); } return NextResponse.next(); }
2. 配置IIS反向代理传递正确请求头
在IIS的web.config中添加反向代理的请求头设置,确保Next.js能获取HTTPS状态:
<configuration> <system.webServer> <rewrite> <rules> <rule name="ReverseProxyInboundRule1" stopProcessing="true"> <match url="(.*)" /> <action type="Rewrite" url="http://localhost:3000/{R:1}" /> <serverVariables> <!-- 传递HTTPS标识变量 --> <set name="HTTP_X_FORWARDED_PROTO" value="https" /> <set name="HTTP_X_ARR_SSL" value="on" /> </serverVariables> </rule> </rules> </rewrite> </system.webServer> </configuration>
注意:需在IIS管理器的「URL重写」模块中,进入「视图服务器变量」,手动添加HTTP_X_FORWARDED_PROTO和HTTP_X_ARR_SSL两个变量,否则配置不会生效。
3. 禁用自定义服务器的重定向逻辑
如果你之前在Express/Koa等自定义服务器代码中添加过HTTPS重定向逻辑,直接删除,避免与IIS、Next.js中间件的规则冲突。
4. 替代方案:直接在IIS层面做HTTPS重定向
如果中间件方式始终有问题,可跳过Next.js中间件,直接在web.config中配置HTTP转HTTPS规则:
<configuration> <system.webServer> <rewrite> <rules> <!-- 优先处理HTTP转HTTPS --> <rule name="HTTP to HTTPS redirect" stopProcessing="true"> <match url="(.*)" /> <conditions> <add input="{HTTPS}" pattern="off" ignoreCase="true" /> </conditions> <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" /> </rule> <!-- 再反向代理到Next.js自定义服务器 --> <rule name="ReverseProxyInboundRule1" stopProcessing="true"> <match url="(.*)" /> <action type="Rewrite" url="http://localhost:3000/{R:1}" /> </rule> </rules> </rewrite> </system.webServer> </configuration>
5. 解决「../pipe...」错误
该错误是IIS的iisnode模块与自定义服务器管道通信异常导致的,可通过以下方式修复:
- 确保自定义服务器监听
localhost:端口,而非0.0.0.0 - 更新iisnode模块至最新稳定版
- 在
web.config中明确指定自定义服务器入口文件:
<configuration> <system.webServer> <iisnode nodeProcessCommandLine="node.exe" /> <handlers> <add name="iisnode" path="server.js" verb="*" modules="iisnode" /> </handlers> <rewrite> <rules> <rule name="DynamicContent"> <match url="/*" /> <action type="Rewrite" url="server.js" /> </rule> </rules> </rewrite> </system.webServer> </configuration>
内容的提问来源于stack exchange,提问作者Nikos Levogiannis
相关产品推荐
相关产品推荐

