在 NextJS 中从服务器端重定向

Redirecting from server side in NextJS

我正在开发一个 Next.JS 应用程序,如果用户的用户名和密码是 correct.However my实施似乎不起作用。

我在 SO 上搜索了有关此的问题,但他们都在谈论使用 getInitialProps 重定向,但这对我没有帮助,因为我想从我的自定义 express 服务器重定向用户。

Login.js

 async handleSubmit(event) {
  event.preventDefault()
  const { username, password } = this.state

  try {
    const response = await fetch('/log_in', {
      method: 'post',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ username, password })
    })
  }

 catch (error) {
    console.log(error)
  }
}  

server.js

app.post('/log_in', (req,res) => {
    console.log(`login form data`);
    console.log(`Username : ${req.body.username}`);
    console.log(`password : ${req.body.password}`);
    if(req.body.username == "user" && req.body.password == "123"){
        res.redirect('/')
    }
}) 

使用Next.JS,您需要在客户端重定向客户端。如果登录成功,请尝试 return 200 状态代码,然后在成功时使用客户端路由器导航到另一个页面。这个例子应该让您了解如何以编程方式将新页面推送到路由器历史记录:

import Router from 'next/router'

() => {
  if(code==200){
    Router.push('/')
  }
}

如果可以的话,SEO 重定向服务器端是个好主意(不是像问题提到的登录)。

但是对于用户语言等,使用这样的服务器端重定向可能是个好主意。

export const getServerSideProps = async ({ req, res }) => {
if (res) {
    res.writeHead(302, { // or 301
      Location: "localized/url/product/categories",
    });
    res.end();
  }
}

Update,我最终得到了这个,因为我确实遇到了一些问题 headers 已经发送。请告诉我如何解决这个问题,因为它不是最理想的(尽管 Google 根据这篇文章确实理解它 https://www.seroundtable.com/google-meta-refresh-redirects-work-25335.html

export default function HomePage({ language }) {
  return (
    <Head>
      <title>-</title>
      <meta httpEquiv="refresh" content={`0;url=/${language}/discover/0`} />
    </Head>
  );
}

更新 Nextjs 正在添加本机支持,有可用的 RFC:https://github.com/vercel/next.js/discussions/17078

这现在可以在 Next.js 10+ 上实现,而无需直接进行任何类型的响应 header 操作。如果满足您的条件,请使用 getServerSideProps or getStaticProps 和 return 一个 redirect 键作为其中的唯一值:

export async function getServerSideProps(context) {
  if(req.body.username == "user" && req.body.password == "123"){
    return {
      redirect: {
        permanent: false,
        destination: "/"
      }
    }
  }
}