我需要将访问者从/Contact
重定向到/contact
。
当我按照文档中的描述进行操作时,我会得到一个无限的重定向循环。
这就是我尝试的:
// next.config.js
async redirects() {
return [
{
source: '/Contact',
destination: '/contact',
permanent: true
}
]
}
使用Next.JS>12您可以使用自定义中间件。
在根文件夹下创建名为middleware.js
的文件,并使用以下代码:
import { NextResponse } from 'next/server';
const Middleware = (req) => {
if (req.nextUrl.pathname === req.nextUrl.pathname.toLowerCase())
return NextResponse.next();
return NextResponse.redirect(new URL(req.nextUrl.origin + req.nextUrl.pathname.toLowerCase()));
};
export default Middleware;
下面将把所有不存在的路径重定向到小写路径。如果未找到路径,则会显示404。
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import Error from 'next/error'
export default function ResolveRoute() {
const router = useRouter()
useEffect(() => {
const { pathname } = router;
if (pathname !== pathname.toLowerCase()) {
router.push(pathname.toLowerCase())
}
},[router])
return <Error statusCode={404} />
}
将该文件名设置为";[route].js";位于页面根目录中的文件夹将充当catch-all(除非页面存在(。这将重定向到小写。如果已经准备好小写,则意味着页面是404。
虽然我很喜欢Andrew的回应,但它是在客户端,我更喜欢服务器端的解决方案。
以下是我受Andrew评论启发所做的事情:
import Custom404 from "./404";
export default function CatchAllRoutes({url}) {
return <Custom404 />
}
export async function getServerSideProps(context) {
const url = context.query.catch;
const { res } = context;
if (url !== url.toLowerCase()) {
res.writeHead(307, {location: `/${url.toLowerCase()}`}) // 307 is temporary while 308 is permanent, choose your preference here..
res.end();
}
else {
context.res.statusCode = 404;
}
return { props: { url } }; // Note: You don't need a prop, but the name of function requires one..
}
我在页面的根目录下命名了文件[catch].js。如果URL与您项目中的任何页面都不匹配,并且URL没有降低大小写,它会降低大小写并重定向到那里,否则我们知道它是404,在这种情况下,我们会给出状态代码404并呈现custom404组件。
遵循Reddit的建议https://www.reddit.com/r/nextjs/comments/hk2qmk/nextjs_routing_case_sensitivity_issue/fwt29n2?utm_source=share&utm_medial=web2x&上下文=3
我使用_error.js
页面组件修复了它。像这样:
import { hasUpperCase } from '../lib/string';
...
Error.getInitialProps = ({ asPath, err, res }) => {
const statusCode = res ? res.statusCode : err ? err.statusCode : 404;
if (asPath && hasUpperCase(asPath)) {
res.writeHead(307, { Location: asPath.toLowerCase() });
res.end();
}
return { statusCode };
};
export default Error;
我也更喜欢像你的例子一样使用重定向。
我发现了这个有用的链接,它涵盖了这个问题的许多解决方案:https://www.youtube.com/watch?v=_vSMITiXAik解决方案1:
- 在
next.config.js
中使用重新编织功能
return [
{
source: "(c|C)(o|O)(n|N)(t|T)(a|A)(c|C)(t|T)",
destination: "/Contact", // here you need to add the exact page contact or Contact
},
];
},
- 使用
_middleware
功能:在页面文件夹中添加一个_middleware.ts
文件
import { NextRequest, NextResponse } from "next/server";
export function middleware(request: NextRequest) {
if (request.nextUrl.pathname === request.nextUrl.pathname.toLocaleLowerCase())
return NextResponse.next();
return NextResponse.redirect(
`${request.nextUrl.origin}${request.nextUrl.pathname.toLocaleLowerCase()}`
);
}
使用此解决方案,您可能需要将页面重命名为小写。
- 使用中间件功能,每个页面都有一个文件夹
您需要保持_middleware.ts
不变,并且需要执行以下步骤:
- 创建一个全部小写的文件夹
contact
- 将您的页面移到此文件夹中
- 在页面中添加指向的
index.ts
。它的conent应该是这样的:
export { default } from "./contact";
- 使用以下扩展名重命名所有页面:如果使用typescript,则为
.page.tsx
或page.ts
;如果使用javascript,则为.page.jsx
或page.js
- 在
next.config.js
中,如果使用typescript,则需要添加此pageExtensions: ["page.tsx", "page.ts"]
;如果使用javascript,则需要增加此pageExtensions: ["page.jsx", "page.js"]
您需要对所有页面执行此操作。
这里有一个非常优雅的解决方案,它还可以继承任何搜索/查询参数:
import { NextResponse } from 'next/server';
const Middleware = (req) => {
if (req.nextUrl.pathname !== req.nextUrl.pathname.toLowerCase()) {
const url = req.nextUrl.clone()
url.pathname = url.pathname.toLowerCase()
return NextResponse.redirect(url)
}
return NextResponse.next();
};
export default Middleware;
当我遇到这个问题时,我注意到NextJS在路径后面添加了一个斜杠。当我在浏览器中查看网络控制台时,我看到状态代码为307和308的请求。一旦我在destination
路径中添加了一个尾部斜杠,我看到很多状态为307的请求,但仍然会出现错误。
一旦我在source
和destination
路径上都添加了一个尾部斜杠,重定向就如预期的那样发生了:
// next.config.js
async redirects() {
return [
{
source: '/Contact/',
destination: '/contact/',
permanent: true
}
]
}