| 对比维度 | cookie | session |
|---|---|---|
| 存储位置 | 浏览器 | 服务器 |
| 体积上限 | 约4KB,具体看浏览器 | 取决于存储介质 |
| 生命周期 | 由Expires/Max-Age控制 | 由应用逻辑控制,可设置超时时间 |
| 安全风险 | 可能被伪造或窃取 | 相对安全,但存在ID泄露风险 |
Secure和HttpOnly属性怎么设置才稳妥
这两个属性是安全底线。HttpOnly防止恶意脚本通过`document.cookie`偷走会话标识,Secure要求只能在HTTPS连接中传输,行业共识认为,凡是涉及登录态的cookie,这两个属性必须同时开启。
部分开发者习惯在本地开发时关闭Secure方便调试,但上线时经常忘记改回来,推荐的做法是通过环境变量区分配置:
const isProduction = process.env.NODE_ENV === 'production';
res.cookie('sessionId', token, {
httpOnly: true,
secure: isProduction,
sameSite: 'strict'
});
向标注成员发送邮件通知怎么实现
与cookie交互的“被动等待”不同,发送邮件是服务端主动发起的操作,你需要三个核心要素:SMTP服务器地址、发件人账户凭证、收件人地址,常见的业务场景是:系统检测到某个标注任务被分配给了成员张三,立即触发一封邮件,告诉他“有一个新任务待处理”。
这里要区分批量通知和单条通知的处理方式,如果你的用户量在数百人以下,使用Node.js的nodemailer库逐个发送即可,成本低,出错了也容易定位。
基本代码骨架:
const nodemailer = require('nodemailer');
const transporter = nodemailer.createTransport({
host: 'smtp.qq.com',
port: 465,
secure: true, // true for 465, false for other ports
auth: {
user: '你的邮箱@qq.com',

pass: '授权码'
}
});
async function sendAssignEmail(toAddress, memberName) {
const info = await transporter.sendMail({
from: '"系统通知" <你的邮箱@qq.com>',
to: toAddress,
subject: '新的标注任务已分配给你',
text: `${memberName},你好:\n\n你有一个新任务,请登录系统查看,`,
html: `<b>${memberName}</b>,你有一个新任务,<a href="https://your-system.com/task/123">点击查看</a>,`
});
console.log('邮件已发送:', info.messageId);
}
QQ邮箱、网易邮箱、Gmail都支持SMTP,但需要用授权码代替密码登录,这是现代邮件服务商的安全策略,你在填认证信息时如果报错,先检查这个。
发邮件前先解决三个基础配置
第一,端口选择,465端口走SSL加密,587端口走STARTTLS加密,25端口是明文,多数云服务商默认封禁25端口,所以别用,发件频率高的话建议选587,兼容性更好。
第二,发件人地址和业务域名一致,用QQ邮箱发件,收件人看到的发件人就是“XXX@qq.com”,信任度较低,可能被对方邮箱判为垃圾邮件,企业场景租用邮件服务时,各项配置成本可以单独核算:基础版的邮件发送服务器费用大概在每年几千元,发送量越大单价越低,具体看服务商的阶梯报价。
第三,失败重试机制,SMTP连接可能超时,收件人邮箱可能满,服务商可能临时限流,没有重试机制,漏发通知的责任就落在你头上,经典做法是加入指数退避重试:
async function sendWithRetry(mailOptions, retries = 3) {
for (let attempt = 1; attempt <= retries; attempt++) {
try {
await transporter.sendMail(mailOptions);
return true;
} catch (err) {
console.error(`第${attempt}次发送失败:`, err.message);
if (attempt === retries) return false;
await new Promise(res => setTimeout(res, Math.pow(2, attempt) 1000));
}
}
}
老系统改造成本高?企业微信通知代替邮件提醒

如果你们的内部协作工具是企业微信或钉钉,用企业微信通知代替邮件提醒是更轻量的方案,不需要配SMTP,不需要处理退信,只要一个机器人Webhook就行。
接入一个群机器人,获得一个Webhook地址,然后POST一段JSON,群成员就收到消息了,这种方式在标注成员数量较少、且已经群组化为前提的团队中,比邮件更快触达,改造也很容易操作,做技术选型时,你的关注重点不必放在“哪种更高级”上,而是评估团队成员的使用习惯:官方文档类的信息适合邮件,紧急任务提醒更适合推送。
curl命令测试企业微信群机器人:
curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的key' \
-H 'Content-Type: application/json' \
-d '{"msgtype": "text", "text": {"content": "新标注任务已分配,请及时处理"}}'
如果你需要给不同城市的标注成员分别发不同内容通知,邮件和企业微信并没有舒服的触达差异,真正有差异的是模板渲染和批量发送代码的组织方式,比如用EJS模板引擎,根据城市和角色生成不同正文,再逐个发送。
代码能跑只是开始,别让这些细节拖后腿
cookie和邮件通知写起来都不难,难点在健壮性和可维护性。
- 时间字段统一用UTC存储,cookie的Expires属性使用GMT格式日期,邮件正文里的截止时间如果直接用服务器本地时间,不同时区的标注成员看到的时间会不一致,容易导致任务逾期。
- 字符编码统一用UTF-8,这是老生常谈,但确实见过不少因为邮件正文中文乱码而影响沟通的案例。
- 邮件通道和业务数据库的事务关系,先写入数据库再发邮件,发完邮件后要把发送状态回写记录,如果发邮件失败而数据库已经更新了任务状态,用户就再也收不到通知,这是常见的坑。
- 日志里不要打印完整cookie值或授权码,排查问题时截断输出,比如只显示前四位。

cookie那边容易被忽视的是容量与数量限制,单个cookie一般不超过4KB,一个域名下的cookie总数也有上限,多数浏览器限制在几十个到上百个不等,如果你往cookie里塞大量业务数据,不仅浪费带宽,还可能触发浏览器丢弃旧cookie的机制,导致会话意外失效。
合理控制cookie的作用范围
把业务无关的字段挪到服务端session,cookie里只保留会话标识符,比如指引用户ID、权限角色这类信息,放在服务端通过session读取,而不是全部堆积到cookie里,这样既提高了安全性,也控制请求体大小。
常见问题答疑:cookie与邮件通知的实操边界
服务器发送cookie时有跨域限制吗
有,浏览器执行同源策略,如果前端的API服务器和后端的托管页面不在同一个域下,`Set-Cookie`默认不会被存储并携带,解决方案是后端在响应头中加`Access-Control-Allow-Credentials: true`,同时设置`SameSite=None; Secure`,注意`SameSite=None`要求必须配合Secure属性,否则现代浏览器会直接拒绝该cookie。
向标注成员发送邮件通知,用第三方通知服务比自己搭SMTP更划算吗
根据团队规模和发送量判断,日均两位数的小团队,自己配置SMTP只花一个邮箱授权码,零成本;日均上千封时,云厂商的邮件推送服务会在后端处理退信、投诉和发送频率限制,避免你的IP被邮件服务商拉黑,第三方服务按量收费,具体费用在厂商官网上都有公开定价,多数情况下,中小团队直接用免费SMTP就够了,频繁触发限流再迁移到专业服务也不迟。
成员一直收不到邮件,怎么排查哪个环节出了问题
按顺序检查三个节点,先看日志确认发送函数是否执行成功,有没有返回`250 OK`状态码;再检查垃圾箱和邮件规则,不少内部邮箱会拦截含链接的自动通知邮件;最后做一次SMTP兼容性检测,换用简单文本格式发送测试,排除HTML模板代码引起的过滤拦击,走到第三步就能定位九成以上的丢失原因。