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

NextJS动态路由生产环境URL末尾自动添加.txt问题

NextJS导出静态站点后动态路由跳转自动添加.txt后缀问题

问题现象

本地开发环境一切正常,但部署到生产服务器后,使用router.push或<Link>组件跳转动态路由时,URL末尾会自动追加.txt后缀。比如跳转/stackoverflow/${questionId}实际会变成/stackoverflow/${questionId}.txt,简单场景下的<Link href="/link">link</Link>也会被重定向到/link.txt。

动态路由文件路径:

src/app/stackoverflow/[questionId]/page.tsx

相关代码与配置

跳转逻辑

function handleConditionClick(questionId) {
    router.push(`/stackoverflow/${questionId}`);
}

同时测试过Link组件写法:

<Link href={`/stackoverflow/${questionId}`}>Open</Link>

NextJS版本

"next": "^13.4.19"

next.config.js配置

/** @type {import('next').NextConfig} */
const nextConfig = {
    output: 'export',
    // Optional: Add a trailing slash to all paths `/about` -> `/about/`
    // trailingSlash: true,
    // Optional: Change the output directory `out` -> `dist`
    distDir: 'build',
};

module.exports = nextConfig;

public/web.config配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
          <rules>
            <rule name="ReactRouter Routes" stopProcessing="true">
              <match url=".*" />
              <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
              </conditions>
              <action type="Rewrite" url="index.html" />
            </rule>
          </rules>
        </rewrite>
    </system.webServer>
    <system.web>
        <authentication mode="None" />
    </system.web>
</configuration>

解决方案

1. 修复IIS重写规则,阻止自动添加扩展名

当前web.config的重写规则只排除了已存在的文件,但IIS会对无扩展名的路径自动尝试匹配默认扩展名(比如.txt)。修改web.config,添加阻止扩展名映射的规则:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
          <rules>
            <!-- 优先处理React路由重写 -->
            <rule name="ReactRouter Routes" stopProcessing="true">
              <match url=".*" />
              <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
              </conditions>
              <action type="Rewrite" url="index.html" />
            </rule>
            <!-- 重定向已添加.txt后缀的路径 -->
            <rule name="Remove TXT Extension" stopProcessing="true">
              <match url="^(.*)\.txt$" />
              <action type="Redirect" url="{R:1}" />
            </rule>
          </rules>
        </rewrite>
        <!-- 设置默认文档为index.html -->
        <defaultDocument>
          <files>
            <add value="index.html" />
          </files>
        </defaultDocument>
        <!-- 禁用IIS自动扩展名映射查找 -->
        <modules runAllManagedModulesForAllRequests="true" />
    </system.webServer>
    <system.web>
        <authentication mode="None" />
    </system.web>
</configuration>

2. 开启NextJS导出的尾随斜杠配置

修改next.config.js,开启trailingSlash: true,让所有路由末尾自动添加斜杠,避免IIS误判路径类型:

/** @type {import('next').NextConfig} */
const nextConfig = {
    output: 'export',
    trailingSlash: true,
    distDir: 'build',
};

module.exports = nextConfig;

3. 检查部署文件结构

确认生产服务器上的build目录结构与本地导出一致,动态路由对应的文件夹(比如build/stackoverflow/[questionId])下存在index.html文件,若部署时文件结构被破坏,也会导致IIS解析路径出错。

内容的提问来源于stack exchange,提问作者KA-Yasso

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:11:24