nodejs中return和res.send的小事

前情提要

这几天在写一个nodejs的项目,为了减少工作量便用了不少不同的AI,包括ClaudeSonnet3.5Gemini Exp。于是就发现代码风格割裂严重,其中就有这个res.send前是否加return这个区别。

叨叨

免得废话,先说结论:强烈建议在res.send前添加return
虽然不添加时IDE也是安安静静没warning,但是还是有隐患

res.send作用

res是给客户端的返回提示,可以使用res.send('xxx')res.json({...})等方式将信息返回给客户端。但是这两者只起到了返回信息给客户端的作用,而不是终止了程序的继续运行。也就是说在这两者之后的代码会在给客户端进行返回后继续执行,如果此时当作程序终止使用,后续缺少条件判断的话容易造成语句误执行。

return作用

return的作用就是终止当前函数,回到调用父函数。程序执行到此处时自然不会执行后续语句。各种语言都有这个,就不多说了。

举例

以下这段代码便是误执行(代码来自 devto):

const express = require('express')
const app = express()
app.use(express.json())
const port = 3000

const JSONdb = require('simple-json-db')
const db = new JSONdb('database.json')

app.post('/login', (req, res) => {
  // Get the password from the POST request body
  const inputPassword = req.body.password

  // Check if user supplied password == the database stored password
  if (inputPassword === db.get("admin")["password"]) {
    res.send("\nLogin Successful!\nWelcome, Admin.\n").status(200)
  } else {
    res.send("\nWrong password!\nAcess denied!\n").status(401)
  }

  // Bug tracker counter - Will reset if code gets down to here,
  // but this should never run because we used res.send()... right?!?!
  db.set("bugTracker", 0);
})

app.listen(port, () => {
  console.log(`Bug-Free Software Corp. App listening on port 3000!`)
  console.log(`It's been ${db.get("bugTracker")} days since we've had a bug!`)
})

这段代码在输入密码之后仍然会执行db.set(),因为res.send并没有结束语句。也就是说每次都要去动一下数据库(此处用了json代替数据库),在大量访问之下极度消耗性能。
这个例子还只是消耗性能,要是抱着不return也没关系的想法,后续的代码执行可能导致各种未定义的行为。导致整体崩溃或者未授权访问。

这个代码修复当然简单,直接加return:

if (inputPassword === db.get("admin")["password"]) {
    // Added `return` to stop further code execution
    return res.send("\nLogin Successful!\nWelcome, Admin.\n").status(200)
  } else {
    // Added `return` to stop further code execution
    return res.send("\nWrong password!\nAcess denied!\n").status(401)
  }

碎碎念

就当是留一个博客给自己长个忘记注意细节的教训吧。

参考资料:

https://dev.to/adamkatora/why-you-should-always-use-return-before-ressend-in-express-apis-and-applications-k9k dev.to的标题党程序员
https://nodejs.org/api/http.html nodejs官方对HTTP操作的详解

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注