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

Posted

技术标签:

【中文标题】在 Next.js 中从大写 URL 重定向到小写 URL【英文标题】:Redirect in Next.js from uppercase to lowercase URL 【发布时间】:2020-12-21 01:04:52 【问题描述】:

我需要将访问者从 /Contact 重定向到 /contact

当我按照in the docs 的描述进行操作时,我得到一个无限重定向循环。

这是我尝试过的:

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

【问题讨论】:

这是意料之中的。路由不区分大小写。 /Contact 和 /contact 与 nextjs 的含义相同。所以它陷入了无限循环。我可以知道您的 /Contact 和 /contact 用例吗?我的意思是为什么您需要重定向这种 url。 @MonzoorTamal 这不是真的;路由区分大小写的;如果没有此重定向,/Contact 将给出 404 而/contact 有效。 redirects 不区分大小写。 (见github.com/vercel/next.js/pull/8848、github.com/vercel/next.js/discussions/15539、reddit.com/r/nextjs/comments/hk2qmk/…)。 【参考方案1】:

借助 Next.JS 12,您现在可以使用自定义中间件。

pages 文件夹下创建名为_middleware.js 的文件并使用此代码:

import  NextResponse  from 'next/server';

const Middleware = (req) => 
  if (req.nextUrl.pathname === req.nextUrl.pathname.toLowerCase())
    return NextResponse.next();

  return NextResponse.redirect(`$req.nextUrl.origin$req.nextUrl.pathname.toLowerCase()`);
;

export default Middleware;

【讨论】:

【参考方案2】:

以下内容会将所有不存在的路径重定向到小写路径。如果找不到路径,则会显示 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”放在您的页面文件夹的根目录中将起到全部作用(除非该页面存在)。这将重定向到小写。如果已经准备好小写,则表示该页面是 404。

【讨论】:

这似乎总是返回一个 404 错误页面,这是有道理的,因为 return &lt;Error ... /&gt; 是无条件的。另请注意,pathname 现在包括params,因此您需要将.toLowerCase() 应用于router.asPath。最后,将其修改为 return null 将使用户转到小写路径,但不会解决 SEO 的任何问题,这需要 301/302 重定向。【参考方案3】:

遵循 Reddit https://www.reddit.com/r/nextjs/comments/hk2qmk/nextjs_routing_case_sensitivity_issue/fwt29n2?utm_source=share&utm_medium=web2x&context=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;

我也更喜欢像你的例子那样使用重定向。

【讨论】:

【参考方案4】:

当我遇到这个问题时,我注意到 NextJS 在路径后面附加了一个斜杠。当我在浏览器中查看我的网络控制台时,我看到了具有交替状态代码 307 和 308 的请求。一旦我在 destination 路径中添加了一个斜杠,我看到了很多状态为 307 的请求,但仍然出现错误。

一旦我在sourcedestination 路径中添加了一个斜杠,重定向就会按预期发生:

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

【讨论】:

以上是关于在 Next.js 中从大写 URL 重定向到小写 URL的主要内容,如果未能解决你的问题,请参考以下文章

尝试使用 next-connect 在 Next.js 中从 http://localhost:3000 重定向到 https://api.twitter.com 时出现 CORS 错误?

Htaccess - 将下划线结合到连字符和大写到小写 301 重定向

Next.js:我们如何将动态路由重定向到静态页面?

Next.js 在 GraphQL 突变内重定向

Next.js 重定向/验证

Next.js:在重定向到 Keycloak 登录页面之前阻止显示索引页面