NextJS 不正确的无服务器 API 路由服务响应

时间:2021-07-26 16:13:17

标签: javascript reactjs next.js server-side-rendering serverless

我正在重新表述我之前提出的这个问题,并提供更多信息,希望能够清楚地了解为什么会发生这种奇怪的行为。

我正在构建一个 NextJS 项目。如果我尝试使用 API 的几个给定路由,例如 loginlogout,我很快就会看到一些意想不到的结果

步骤:

  1. api/users/login发送“POST”请求
  2. 收到回复——第一个回复没问题。

第一反应:

//Comes from createAndSendToken util method -- expected result of login API call
{
"success":  true,
"token":  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYwYjZkNTVlZGRkYTEzNWFlMzZiMTk2YSIsImlhdCI6MTYyNzMxMzc0MCwiZXhwIjoxNjMyNDk3NzQwfQ.fb-kpSbpngSJfAJxDDbi7xbItTfSv1Ha8FMnsGBe9Dg",
    "user":  {
    "id":  "60b6d55eddda135ae36b196a",
    "role":  "admin",
    "name":  "admin",
    "email":  "admin@test.com"
    }
}

控制台输出:

ready - started server on 0.0.0.0:3000, url: http://localhost:3000
info  - Loaded env from /home/john/code/projects/current/next-with-api/.env.local
info  - Using webpack 5. Reason: Enabled by default https://nextjs.org/docs/messages/webpack5
event - compiled successfully
event - build page: /api/users/login
wait  - compiling...
event - compiled successfully

步骤,续

  1. ...
  2. ...
  3. api/users/logout发送“POST”请求
  4. 收到回复——仍然正确

第二反应:

//Comes from api/users/logout -- correct response for this API call
{
"success":  true,
"message":  "logged out"
}

控制台输出

ready - started server on 0.0.0.0:3000, url: http://localhost:3000
info  - Loaded env from /home/john/code/projects/current/next-with-api/.env.local
info  - Using webpack 5. Reason: Enabled by default https://nextjs.org/docs/messages/webpack5
event - compiled successfully
event - build page: /api/users/login
wait  - compiling...
event - compiled successfully
event - build page: /api/users/logout 
wait  - compiling...
event - compiled successfully

步骤,续

  1. ...
  2. ...
  3. ...
  4. ...
  5. api/users/login发送“POST”请求
  6. 接收响应 - 现在不正确

预期结果: 与上面的第一个响应相同的响应。响应应该来自 createAndSendToken 函数。

实际结果 响应来自 logout API 路由,即使请求未发送到此端点。请求已发送至 api/users/login,因此不应从 api/users/logout 端点运行代码。

第三次回应:

{
"success":  true,
"message":  "logged out"
}

控制台输出:

ready - started server on 0.0.0.0:3000, url: http://localhost:3000
info  - Loaded env from /home/john/code/projects/current/next-with-api/.env.local
info  - Using webpack 5. Reason: Enabled by default https://nextjs.org/docs/messages/webpack5
event - compiled successfully
event - build page: /api/users/login
wait  - compiling...
event - compiled successfully
event - build page: /api/users/logout
wait  - compiling...
event - compiled successfully

请注意,在上面的控制台输出中,最近构建的页面是 logout --> 值得注意,因为我收到来自 logout 的响应而不是预期的 login.. . 预期的行为是,当我向指定的 API 端点(在本例中为 api/users/login,服务器将运行事件 > build page: /api/users/login > 并且我将收到来自那里。相反,这似乎并没有发生,而且我从最近构建的页面收到了我的回复 - api/users/logout - 这没有任何意义,也不是我所期望的。

登录文件:

const handler = nc.use(dbConnect).post(async (req, res) => {
    const { email, password } = req.body

    if (!email || !password) {
        res.status(400).json({
            success: false,
            message: 'Email and password required.',
        })
    }

    const user = await User.findOne({ email }).select('+password')

    if (!user || !(await user.correctPassword(password, user.password))) {
        res.status(401).json({
            success: false,
            message: 'Incorrect email or password',
        })
    } else createAndSendToken(user, 200, req, res)
})

注销文件:

const handler = nc.post((req, res) => {
    const cookies = new Cookies(req, res)
    cookies.set('jwt', 'logged_out', {
        expires: new Date(Date.now() + 10 * 1000),
        httpOnly: true,
    })
    res.status(200).json({
        success: true,
        message: 'logged out',
    })
})

createAndSendToken 实用函数

export const createAndSendToken = (user, statusCode, req, res) => {
    const token = signToken(user._id)
    const cookies = new Cookies(req, res)
    const cookieOptions = {
        expires: new Date(Date.now() + process.env.JWT_COOKIE_EXPIRES_IN * 1000),
        httpOnly: true,
    }

    if (process.env.NODE_ENV === 'production') cookieOptions.secure = true
    cookies.set('jwt', token, cookieOptions)

    user.password = undefined

    const { id, role, name, email } = user

    res.status(statusCode).json({
        success: true,
        token,
        user: {
            id,
            role,
            name,
            email,
        },
    })
}
  • 请注意,如果我颠倒顺序也会发生这种情况,并且我的应用程序中的其他 API 路由可能也会发生这种情况。例如,有时当我在最近登录后尝试退出时,我会收到来自 api/users/login 而不是预期的 api/users/logout 的响应。

  • 另请注意,无论我使用什么客户端,都会发生这种情况。我首先在浏览器中注意到了这种行为,但我也一直使用 Postman 重新创建它。在客户端,我可以验证请求是否被发送到正确的端点。在服务器端,请求被错误的处理程序处理的地方似乎发生了一些奇怪的事情。

  • 最后请注意,这与 React 文件无关。如果您查看项目,请忽略这些。我创建了一个 git 分支,并在其中删除了那些并严格仅与 API 交互,但仍然遇到此问题。

其他环境注意事项:

  • 使用 mongoDB 和 next-connect 构建 API 路由并连接到数据库

有人遇到过这种情况吗?我应该完全重新考虑我的整个 API 吗?我在使用 NextJS 时做错了什么吗?看起来这应该是构建 API 的合适方法,而且我当然希望能够可靠地使用这些端点。我真的很困惑为什么会这样。

Project Link

0 个答案:

没有答案