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
相关产品推荐
相关产品推荐

