参阅:bellard.org : QuickJS 如何使用 qjs 执行 js 脚本
在 QuickJS 中发送邮件需要依赖外部库或调用系统命令,因为 QuickJS 本身不包含 SMTP 功能。以下是两种实现方法:
方法 1:调用系统命令(推荐)
使用 QuickJS 的 std
模块调用 curl
命令发送邮件(适用于 Linux/macOS):
// 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('邮件发送完成');
运行命令:
qjs sendmail.js
方法 2:使用原生模块(需要编译)
需要编写 C 扩展模块并编译进 QuickJS:
- 创建
mailer.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;
}
- 编译 QuickJS 并链接 libesmtp:
gcc -o qjs mailer.c qjs.c -Iquickjs -lesmtp -lssl -lcrypto
- 在 QuickJS 中使用:
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']
});
注意事项:
-
curl 方法要求:
- 系统需安装 curl (7.20.0+)
- 附件需可读且大小不超过邮件服务器限制
- 敏感信息建议从环境变量读取
-
安全建议:
// 从环境变量读取凭据 const username = std.getenv('SMTP_USER'); const password = std.getenv('SMTP_PASS');
-
Windows 系统:
- 使用 PowerShell 的
Send-MailMessage
:
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}"`);
- 使用 PowerShell 的
-
替代方案:
- 使用 HTTP API 发送(如 Mailgun/SendGrid)
- 调用 Python/Node.js 脚本处理邮件发送
对于简单需求,调用系统命令是最快实现方式。对于复杂应用,建议使用 Node.js 等更成熟的运行时环境。