Next.js 构建阶段在服务器操作中使用 getServerSession 时出现异常

问题描述 投票:0回答:1

我正在阅读如何使用服务器操作通过从不将此类数据发送到客户端来将敏感数据保留在服务器上。例如,我认为这对于保留访问令牌可能很有用。然后,我在客户端编写代码来调用服务器操作来执行特权操作。这工作正常,但需要注意的是,如果在构建步骤中执行此设置,则该设置将不起作用。

我在服务器上有类似的东西,它使用

axios
拦截器 将访问令牌插入到每个请求的授权标头中。

axios.interceptors.request.use(async req => {
    const session = await getServerSession(authOptions)
    req.headers.authorization = `Bearer ${session.access_token}`;
    return req;
});

但是,

getServerSession()
在编译路线时会导致问题。也就是说,当使用例如npm run build
直接
在使用例如时进行服务器操作调用时generateStaticParams
。无论哪种情况,您都会看到类似的错误。

rpm run build


Error: Invariant: headers() expects to have requestAsyncStorage, none available. at u (/mnt/.next/server/chunks/472.js:30:26016) at s (/mnt/.next/server/chunks/472.js:30:20315) at /mnt/.next/server/chunks/881.js:1:10082 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async m (/mnt/.next/server/chunks/881.js:1:9490) at async Object.x [as generateStaticParams] (/mnt/.next/server/app/posts/[slug]/page.js:1:3453) at async buildParams (/mnt/node_modules/next/dist/build/utils.js:1025:40)

npm run dev


Error: Invariant: headers() expects to have requestAsyncStorage, none available. at headers (webpack-internal:///(rsc)/./node_modules/next/dist/client/components/headers.js:38:15) at getServerSession (webpack-internal:///(rsc)/./node_modules/next-auth/next/index.js:107:41) at eval (webpack-internal:///(rsc)/./lib/server.ts:32:86) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async getAllPosts (webpack-internal:///(rsc)/./lib/server.ts:43:9) at async Object.generateStaticParams (webpack-internal:///(rsc)/./app/posts/[slug]/page.tsx:32:13) at async buildParams (/mnt/node_modules/next/dist/build/utils.js:1025:40) ✓ Compiled /editor/update/[slug] in 216ms (1737 modules)
我的代码大致如下:

/app/posts/[slug]/page.tsx


export async function generateStaticParams() { return (await getAllPosts()).map((slug: string) => ({ slug })) }

/lib/server.ts


'use server' axios.interceptors.request.use(async req => { const session = await getServerSession(authOptions) req.headers.authorization = `Bearer ${session.access_token}`; return req; }); export async function getAllPosts(): Promise<string[]> { let slugs: string[] = [] await axios.get('/api/slugs/).then((r) => { slugs = r.data }) return slugs }
知道这是怎么回事吗?我是否做了一些明显不正确的事情?流程是:

generateStaticParams (during build)

 -> 
getAllPosts (server)
 -> 
getServerSession (server)

在服务器操作中使用 axios 拦截器

似乎确实有效 - 它只是在任何类型的编译步骤中调用时不起作用有什么想法吗?我在这里做错了什么?构建期间当然没有“会话”。尽管我期望它返回 null 或类似的值,而不是抛出错误。也许答案就是抓住它而不做任何事情?

node.js next.js build generatestaticparams
1个回答
0
投票
getServerSession(authOptions)

,这会导致错误,因为

getServerSession
函数依赖于在构建或静态生成期间不可用的服务器端功能。
这里有两种解决方法:

  1. 条件拦截器

    :仅当拦截器在服务器上运行时才附加拦截器。您可以检查 process.browser 是否为

    true
    来确定代码是在浏览器中运行还是在服务器上运行。
    if (process.browser) {
      axios.interceptors.request.use(async req => {
        const session = await getServerSession(authOptions)
        req.headers.authorization = `Bearer ${session.access_token}`;
        return req;
      });
    }
    

    这样,拦截器仅在客户端运行时使用,并且不会在构建步骤期间干扰服务器端操作。

  2. 服务器操作的后备

    :如果您在服务器操作中使用getServerSession,则可以在构建或静态生成期间调用时提供后备或默认值。这可以帮助防止错误。

    export async function getServerSessionFallback(authOptions) {
      if (process.browser) {
        return getServerSession(authOptions);
      } else {
        // Provide a fallback value (e.g., null) for server-side usage during build.
        return null;
      }
    }
    

    然后,在拦截器或服务器操作中使用 
    getServerSessionFallback

    
    

© www.soinside.com 2019 - 2024. All rights reserved.