QuickJS 如何发送一封邮件 ?
参阅: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 等更成熟的运行时环境。
相关文章:
QuickJS 如何发送一封邮件 ?
参阅:bellard.org : QuickJS 如何使用 qjs 执行 js 脚本 在 QuickJS 中发送邮件需要依赖外部库或调用系统命令,因为 QuickJS 本身不包含 SMTP 功能。以下是两种实现方法: 方法 1:调用系统命令(推荐) 使…...
clickhouse 和 influxdb 选型
以下是 ClickHouse、InfluxDB 和 HBase 在体系架构、存储引擎、数据类型、性能及场景的详细对比分析: 🏗️ 一、体系架构对比 维度ClickHouseInfluxDBHBase设计目标大规模OLAP分析,高吞吐复杂查询 时序数据采集与监控,优化时间线管理高吞吐随机…...

GOOUUU ESP32-S3-CAM 果云科技开发板开发指南(一)(超详细!)Vscode+espidf 通过摄像头拍摄照片并存取到SD卡中,文末附源码
看到最近好玩的开源项目比较多,就想要学习一下esp32的开发,目前使用比较多的ide基本上是arduino、esp-idf和platformio,前者编译比较慢,后两者看到开源大佬的项目做的比较多,所以主要学习后两者。 本次使用的硬件是GO…...
C++学习思路
C++知识体系详细大纲 一、基础语法 (一)数据类型 基本数据类型 整数类型(int, short, long, long long)浮点类型(float, double, long double)字符类型(char, wchar_t, char16_t, char32_t)布尔类型(bool)复合数据类型 数组结构体(struct)联合体(union)枚举类型…...

全流程开源!高德3D贴图生成系统,白模一键生成真实感纹理贴图
导读 MVPainter 随着3D生成从几何建模迈向真实感还原,贴图质量正逐渐成为决定3D资产视觉表现的核心因素。我们团队自研的MVPainter系统,作为业内首个全流程开源的3D贴图生成方案,仅需一张参考图与任意白模,即可自动生成对齐精确…...
使用Conda管理服务器多版本Python环境的完整指南
在服务器环境中管理多个Python版本是开发者和系统管理员常见的需求,尤其是当不同项目依赖特定版本的Python时。本文将重点介绍如何通过Conda实现多版本Python的隔离与管理,确保服务器环境的稳定性和灵活性。 为什么需要多版本Python管理? 服…...

html 滚动条滚动过快会留下边框线
滚动条滚动过快时,会留下边框线 但其实大部分时候是这样的,没有多出边框线的 滚动条滚动过快时留下边框线的问题通常与滚动条样式和滚动行为有关。这种问题可能出现在使用了自定义滚动条样式的情况下。 注意:使用方法 6 好使,其它…...

数据通信与计算机网络——数据与信号
主要内容 模拟与数字 周期模拟信号 数字信号 传输减损 数据速率限制 性能 注:数据必须被转换成电磁信号才能进行传输。 一、模拟与数字 数据以及表示数据的信号可以使用模拟或者数字的形式。数据可以是模拟的也可以是数字的,模拟数据是连续的采用…...

【LLM大模型技术专题】「入门到精通系列教程」LangChain4j与Spring Boot集成开发实战指南
LangChain4j和SpringBoot入门指南 LangChain4jLangchain4j API语言模型消息类型内存对象ChatMemory接口的主要实现设置 API 密钥SpringBoot Configuration配置ChatLanguageModelStreamingChatLanguageModel初始化ChatModel对象模型配置分析介绍说明通过JavaConfig创建ChatModel…...
Flask 基础与实战概述
一、Flask 基础知识 什么是 Flask? Flask 是一个基于 Python 的轻量级 Web 框架(微框架)。 特点:核心代码简洁,给予开发者更多选择空间。 与 Django 对比: Django 创建空项目生成多个文件,Flask 仅需一个文件即可实现简单应用(如 "Hello, World!")。 Flask …...
东芝Toshiba e-STUDIO2110AC打印机信息
基本信息 产品类型:数码复合机颜色类型:彩色涵盖功能:复印、打印、扫描接口类型:标配为 Ethernet(RJ45)10/100/1000BASE - T、USB2.0 高速;选配为 Wireless Lan、IEEE802.11b/g/n、blueteeth。中…...

Vue3 GSAP动画库绑定滚动条视差效果 绑定滚动条 滚动条动画 时间轴
介绍 GSAP 用于创建高性能、可控制的动画效果。由 GreenSock 团队开发,旨在提供流畅、快速、稳定的动画效果,并且兼容各种浏览器。 提供了多个插件,扩展了动画的功能,如 ScrollTrigger(滚动触发动画)、Dra…...

grafana-mcp-analyzer:基于 MCP 的轻量 AI 分析监控图表的运维神器!
还在深夜盯着 Grafana 图表手动排查问题?今天推荐一个让 AI 能“读图说话”的开源神器 —— grafana-mcp-analyzer。 想象一下这样的场景: 凌晨3点,服务器告警响起。。。你睁着惺忪的眼睛盯着复杂的监控图表 😵💫花…...
git commit 执行报错 sh: -/: invalid option
目录 目录 1. 检查 Git 钩子脚本(核心步骤)2. 临时绕过钩子(快速提交)3. 修复钩子依赖环境4. 重新初始化 Husky(如适用)5. 验证用户配置 Tips: 如果是 clone 下来的新项目直接进行 步骤 4 。…...
uniapp 设置手机不息屏
在使用 UniApp 开发应用时,有时需要在设备长时间未操作时实现息屏保护功能,以节省电量和保护屏幕。以下是如何在 UniApp 中实现这一功能的步骤。 示例一 // 保持屏幕常亮 uni.setKeepScreenOn({keepScreenOn: true });// 监听应用进入后台事件 uni.onH…...

【题解-洛谷】B3622 枚举子集(递归实现指数型枚举)
题目:B3622 枚举子集(递归实现指数型枚举) 题目描述 今有 n n n 位同学,可以从中选出任意名同学参加合唱。 请输出所有可能的选择方案。 输入格式 仅一行,一个正整数 n n n。 输出格式 若干行,每行…...

(LeetCode 每日一题)3170. 删除星号以后字典序最小的字符串(贪心+栈)
题目:3170. 删除星号以后字典序最小的字符串 思路:贪心栈,时间复杂度0(n)。 对于每一个‘ * ’,优先选最右边的最小字符,才会使最终得到的字符串最小。 用栈,来记录每个字符的位置下标。细节看注释。 C版本…...
Protobuf 中的类型查找规则
a.proto syntax "proto2"; //protoc3生成代码兼容proto2语法 package pkgA; message Example { }ba.proto package pkgB.pkgA; message Example { }b.proto syntax "proto3"; //protoc3生成代码兼容proto2语法 package pkgB; import "test1/a.pr…...
Python项目中添加环境配置文件
在Python项目中添加配置文件有多种方式,每种方式对应不同的依赖包和读取方法。以下是 7种主流配置管理方案,包含安装命令、配置示例和变量读取方法: 1. .env 文件(推荐简单项目) 依赖包: python-dotenv pip install …...
【区块链基础】区块链的 Fork(分叉)深度解析:原理、类型、历史案例及共识机制的影响
区块链的 Fork(分叉)全面解析:原理、类型、历史案例及共识机制的影响 在区块链技术的发展过程中,Fork(分叉)现象是不可避免且极具影响力的一个环节。理解区块链分叉的形成原因、具体表现以及共识机制对分叉的作用,对于深入把握区块链技术架构及其治理机制至关重要。 本…...
IOS 打包账号发布上传和IOS Xcode证书配置
xcode下载 https://developer.apple.com/download/all/ App发布 https://appstoreconnect.apple.com/ https://appstoreconnect.apple.com/teams/83ba877c-af24-4fa5-aaf2-e9b9b6066e82/apps/6473148620/testflight/groups/eb983352-b2e2-4c29-bbb7-071bf7287795 https://devel…...

使用 HTML + JavaScript 实现文章逐句高亮朗读功能
在这个信息爆炸的时代,我们每天都要面对大量的文字阅读。无论是学习、工作还是个人成长,阅读都扮演着至关重要的角色。然而,在快节奏的生活中,我们往往难以找到足够的安静时间专注于阅读。本文用 HTML JavaScript 实现了一个基于…...
【CSS-4】掌握CSS文字样式:从基础到高级技巧
文字是网页内容的核心载体,良好的文字样式设计不仅能提升可读性,还能增强网站的整体视觉效果。本文将全面介绍CSS中控制文字样式的各种属性和技巧,帮助您打造专业级的网页排版。 1. 基础文字属性 1.1 字体设置 (font-family) body {font-f…...

双碳时代,能源调度的难题正从“发电侧”转向“企业侧”
安科瑞刘鸿鹏 摘要 在“双碳”战略和能源结构转型的大背景下,企业储能电站逐步成为提升能源利用效率、增强用能韧性的重要手段。随着系统规模扩大与运行复杂度提升,如何对光伏、储能、负荷等流进行实时调控,成为智慧用能的关键。ACCU100微…...

3. 简述node.js特性与底层原理
😺😺😺 一、Node.js 底层原理(简化版) Node.js 是一个 基于 Chrome V8 引擎构建的 JavaScript 运行时,底层核心由几部分组成: 组成部分简要说明 1.V8 引擎 将 JS 编译成机器码执行࿰…...

OpenCV CUDA模块图像处理------创建一个模板匹配(Template Matching)对象函数createTemplateMatching()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 创建一个用于在 GPU 上执行模板匹配的 TemplateMatching 对象。 该函数返回一个指向 TemplateMatching 的智能指针(Ptr)…...

【Kubernetes】K8s 之 ETCD - 恢复备份
ETCD 是一个高可用的分布式键值存储,常用于存储配置信息和服务发现等。当系统出现故障或数据损坏时,能够快速恢复成先前的状态是维护系统稳定性的关键。ETCD 提供了备份和恢复功能,以确保数据持久性和可靠性,一起来看看如何操作吧…...
CMS、G1、ZGC、Shenandoah 的全面对比
大家好,这里是架构资源栈!点击上方关注,添加“星标”,一起学习大厂前沿架构! Java 垃圾回收器从最早的 Serial 一步步演化,如今已经有了多款高性能、低延迟的 GC 垃圾收集器可选,比如 CMS、G1、…...

RabbitMQ 学习
MQ 的相关概念 什么是 MQ MQ(message queue),从字面意思上看,本质是个队列,FIFO 先入先出,只不过队列中存放的内容是 message 而已,还是一种跨进程的通信机制,用于上下游传递消息。…...

如何轻松、安全地管理密码(新手指南)
很多人会为所有账户使用相同、易记的密码,而且常常多年不换。虽然这样方便记忆,但安全性非常低。 您可能听说过一些大型网站的信息泄露事件,同样的风险也可能存在于您的WordPress网站中。如果有不法分子获取了访问权限,您的网站和…...