【问题标题】:Next.js: res.redirect in getServerSideProps (res.redirect is not a function)Next.js:getServerSideProps 中的 res.redirect(res.redirect 不是函数)
【发布时间】:2021-10-07 07:19:12
【问题描述】:

我正在使用next-connect 将一些快速中间件应用于我的 next.js 应用程序。在尝试添加csrf中间件时,遇到如下错误:

res.redirect is not a function

此错误仅在我在 getServerSideProps 中应用中间件时出现,它在我的 API 端点中运行良好。
例如:

// in /pages/api/test.ts
nc()
 .use(db)
 .use(initializedSession)
 .use(csrfProtection)
 .use(initializedPassport)
 .use(initializedPassportSession)
 .post(
    passport.authenticate("local", {failureRedirect: "/login"}),
    (req: NextApiRequest, res: NextApiResponse, next) => {
       return res.redirect("/");
    }
 )

确实有效,但在 getServerSideProps 中应用相同的反应页面:

// In /pages/login.tsx
export const getServerSideProps: GetServerSideProps = async ({req, res}) => {
  await nc()
    .use(db)
    .use(initializedSession)
    .use(csrfProtection)
    .use(initializedPassport)
    .use(initializedPassportSession)
  .run(req, res);
  return {
    props: {
      csrfToken: req.csrfToken(),
    },
  };
};

不起作用并导致res 没有重定向方法。

我不太确定这种行为,但我确定我错过了一些愚蠢的东西。有什么想法吗?

【问题讨论】:

  • 啊哈,这完全有道理!有什么理由会出现这种情况吗?有没有办法在getServerSideProps 中扩展http.ServerResponse?
  • @brc-dd 谢谢,我也在看!我会尝试用它来转换响应。看起来很简单,但我感觉会有一些陷阱,否则 next.js 团队可能会自己实现它。无论哪种方式,您的回答都是我正在寻找的答案!我不能让它正确,因为它太短了。如果您想要其中一些 Stackoverflow 点,请随时写一些更长的内容,我会将您的回复标记为解决方案:)

标签: next.js


【解决方案1】:

getServerSideProps 的 res 对象属于 http.ServerResponse 类型,并且没有名为 redirect 的方法。而在 API 中,res 对象是 NextApiResponse,具有 some additional helpers,就像 redirect 方法一样。这就是您的代码在 API 逻辑中运行良好的原因。

但 Next.js 建议这样做:

注意:您不应使用fetch() 调用getServerSideProps 中的API 路由。相反,直接导入 API 路由中使用的逻辑。您可能需要针对这种方法稍微重构您的代码。

从外部 API 获取没问题!

因此,您的方法在其核心方面非常好,但要使其发挥作用,您将“稍微重构”您的代码。现在,Next.js 在内部使用了一个apiResolver 中间件。您可以尝试使用它或您的自定义解析器。

请注意,内部 API 容易更改,因此通常不建议在生产代码中直接使用它们。但是您可以轻松地将链接文件中的逻辑克隆到您自己的共享库中。

要处理响应部分,您可以执行以下操作:

import type { GetServerSideProps, NextApiRequest, NextApiResponse } from 'next';

import {
  redirect,
  sendData,
  sendJson,
  sendStatusCode,
} from 'next/dist/next-server/server/api-utils'; // or from 'custom-api-resolver'

// component logic here ...

const getServerSideProps: GetServerSideProps = async ({
  req: apiReq,
  res: apiRes,
}) => {
  const req = apiReq as NextApiRequest;
  const res = apiRes as NextApiResponse;

  res.status = (statusCode) => sendStatusCode(res, statusCode);
  res.send = (data) => sendData(req, res, data);
  res.json = (data) => sendJson(res, data);
  res.redirect = (statusOrUrl: number | string, url?: string) =>
    redirect(res, statusOrUrl, url);

  // api logic here...

  return { props: {} };
};

export { getServerSideProps };

参考资料:

我还没有彻底测试过这个,但是对于基础来说,这应该可以正常工作。

【讨论】:

    猜你喜欢
    • 2022-06-28
    • 2012-09-08
    • 2018-08-01
    • 1970-01-01
    • 2016-06-13
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多