QuickJS 如何发送一封邮件 ?

参阅:bellard.org‌ : QuickJS 如何使用 qjs 执行 js 脚本

在 QuickJS 中发送邮件需要依赖外部库或调用系统命令,因为 QuickJS 本身不包含 SMTP 功能。以下是两种实现方法:

方法 1:调用系统命令(推荐)

使用 QuickJS 的 std 模块调用 curl 命令发送邮件(适用于 Linux/macOS):

javascript 复制代码
// qjs sendmail.js
import * as std from 'std';

// 邮件配置
const smtpServer = 'smtp://smtp.example.com:587';
const username = 'your_email@example.com';
const password = 'your_password';
const from = 'sender@example.com';
const to = 'recipient@example.com';
const subject = 'QuickJS 邮件测试';
const body = '这是一封来自 QuickJS 的测试邮件';
const attachmentPath = '/path/to/attachment.txt';

// 构建 curl 命令
const command = [
  'curl',
  '--url', smtpServer,
  '--user', `${username}:${password}`,
  '--mail-from', from,
  '--mail-rcpt', to,
  '--upload-file', '-',
  '--ssl-reqd'
].join(' ');

// 构建 MIME 邮件内容
const boundary = 'quickjs-boundary';
const mimeMessage = [
  `From: <${from}>`,
  `To: <${to}>`,
  `Subject: ${subject}`,
  `MIME-Version: 1.0`,
  `Content-Type: multipart/mixed; boundary="${boundary}"`,
  '',
  `--${boundary}`,
  'Content-Type: text/plain; charset=utf-8',
  '',
  body,
  '',
  `--${boundary}`,
  `Content-Type: application/octet-stream; name="${attachmentPath.split('/').pop()}"`,
  'Content-Disposition: attachment',
  'Content-Transfer-Encoding: base64',
  '',
  std.loadFile(attachmentPath, 'binary').toString('base64'),
  '',
  `--${boundary}--`
].join('\r\n');

// 执行命令
const proc = std.popen(command, 'w');
proc.puts(mimeMessage);
proc.close();

console.log('邮件发送完成');

运行命令:

bash 复制代码
qjs sendmail.js

方法 2:使用原生模块(需要编译)

需要编写 C 扩展模块并编译进 QuickJS:

  1. 创建 mailer.c
c 复制代码
#include "quickjs.h"
#include <libesmtp.h>

static JSValue sendMail(JSContext *ctx, JSValueConst this_val,
                        int argc, JSValueConst *argv) {
    // 实现 SMTP 邮件发送逻辑
    // 使用 libesmtp 库 (https://libesmtp.github.io/)
    // ...
}

static const JSCFunctionListEntry funcs[] = {
    JS_CFUNC_DEF("send", 1, sendMail),
};

static int mailer_init(JSContext *ctx, JSModuleDef *m) {
    return JS_SetModuleExportList(ctx, m, funcs, countof(funcs));
}

JSModuleDef *js_init_module_mailer(JSContext *ctx, const char *module_name) {
    JSModuleDef *m = JS_NewCModule(ctx, module_name, mailer_init);
    if (!m) return NULL;
    JS_AddModuleExportList(ctx, m, funcs, countof(funcs));
    return m;
}
  1. 编译 QuickJS 并链接 libesmtp:
bash 复制代码
gcc -o qjs mailer.c qjs.c -Iquickjs -lesmtp -lssl -lcrypto
  1. 在 QuickJS 中使用:
javascript 复制代码
import * as mailer from 'mailer';

mailer.send({
  server: 'smtp.example.com:587',
  user: 'your_email@example.com',
  pass: 'your_password',
  from: 'sender@example.com',
  to: 'recipient@example.com',
  subject: '测试邮件',
  body: '邮件正文',
  attachments: ['/path/to/file.txt']
});

注意事项:

  1. curl 方法要求

    • 系统需安装 curl (7.20.0+)
    • 附件需可读且大小不超过邮件服务器限制
    • 敏感信息建议从环境变量读取
  2. 安全建议

    javascript 复制代码
    // 从环境变量读取凭据
    const username = std.getenv('SMTP_USER');
    const password = std.getenv('SMTP_PASS');
  3. Windows 系统

    • 使用 PowerShell 的 Send-MailMessage
    javascript 复制代码
    const psCommand = [
      `Send-MailMessage`,
      `-From '${from}'`,
      `-To '${to}'`,
      `-Subject '${subject}'`,
      `-Body '${body}'`,
      `-Attachments '${attachmentPath}'`,
      `-SmtpServer '${smtpServer.split(':')[0]}'`,
      `-Port ${smtpServer.split(':')[1] || 587}`,
      `-Credential (New-Object System.Management.Automation.PSCredential('${username}', (ConvertTo-SecureString '${password}' -AsPlainText -Force)))`
    ].join(' ');
    
    std.system(`powershell -Command "${psCommand}"`);
  4. 替代方案

    • 使用 HTTP API 发送(如 Mailgun/SendGrid)
    • 调用 Python/Node.js 脚本处理邮件发送

对于简单需求,调用系统命令是最快实现方式。对于复杂应用,建议使用 Node.js 等更成熟的运行时环境。

相关推荐
amy_jork8 分钟前
npm删除包
开发语言·javascript·ecmascript
max5006002 小时前
基于桥梁三维模型的无人机检测路径规划系统设计与实现
前端·javascript·python·算法·无人机·easyui
我命由我123453 小时前
软件开发 - 避免过多的 if-else 语句(使用策略模式、使用映射表、使用枚举、使用函数式编程)
java·开发语言·javascript·设计模式·java-ee·策略模式·js
萌萌哒草头将军3 小时前
Node.js v24.6.0 新功能速览 🚀🚀🚀
前端·javascript·node.js
AALoveTouch4 小时前
大麦APP抢票揭秘
javascript
持久的棒棒君5 小时前
启动electron桌面项目控制台输出中文时乱码解决
前端·javascript·electron
小小愿望7 小时前
移动端浏览器中设置 100vh 却出现滚动条?
前端·javascript·css
烛阴8 小时前
TypeScript 接口入门:定义代码的契约与形态
前端·javascript·typescript
掘金安东尼8 小时前
使用自定义高亮API增强用户‘/’体验
前端·javascript·github
夏日不想说话9 小时前
API请求乱序?深入解析 JS 竞态问题
前端·javascript·面试