在Next.js中将URL从大写重定向到小写



我需要将访问者从/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:

  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
},
];
},
  1. 使用_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()}`
);
}

使用此解决方案,您可能需要将页面重命名为小写。

  1. 使用中间件功能,每个页面都有一个文件夹

您需要保持_middleware.ts不变,并且需要执行以下步骤:

  • 创建一个全部小写的文件夹contact
  • 将您的页面移到此文件夹中
  • 在页面中添加指向的index.ts。它的conent应该是这样的:
export { default } from "./contact";
  • 使用以下扩展名重命名所有页面:如果使用typescript,则为.page.tsxpage.ts;如果使用javascript,则为.page.jsxpage.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的请求,但仍然会出现错误。

一旦我在sourcedestination路径上都添加了一个尾部斜杠,重定向就如预期的那样发生了:

// next.config.js
async redirects() {
return [
{
source: '/Contact/',
destination: '/contact/',
permanent: true
}
]
}

相关内容

  • 没有找到相关文章

最新更新