问题描述
我正在使用 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
类型,并且没有名为 redirect
的方法。而在 API 中,res
对象是 NextApiResponse
,与 redirect
方法一样具有 some additional helpers。这就是您的代码在 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 };
参考文献:
- https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering
- https://nextjs.org/docs/api-routes/introduction
我还没有彻底测试过这个,但对于基础知识,这应该可以正常工作。