ASP 发送电子邮件
CDONTS / CDO.Message 发信、SMTP 配置、HTML 邮件与附件。
最简单的发信
<%
Dim mail
Set mail = Server.CreateObject("CDO.Message")
mail.From = "noreply@example.com"
mail.To = "user@example.com"
mail.Subject = "注册确认"
mail.TextBody = "请点击链接完成注册。"
' 指定 SMTP 服务器
mail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
mail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.example.com"
mail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
mail.Configuration.Fields.Update
mail.Send
Set mail = Nothing
Response.Write "邮件已发送"
%>邮件已发送sendusing = 2 means network SMTP (1 drops into a local queue directory). All three configuration fields are required; a missing one yields "the transport cannot connect to the server".
需要认证的 SMTP
<%
Dim cfg, mail
Set cfg = Server.CreateObject("CDO.Configuration")
cfg.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
cfg.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.example.com"
cfg.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 587
cfg.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
cfg.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "apiuser"
cfg.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "secret"
cfg.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
cfg.Fields.Update
Set mail = Server.CreateObject("CDO.Message")
Set mail.Configuration = cfg
mail.From = "noreply@example.com"
mail.To = "user@example.com"
mail.Subject = "测试"
mail.TextBody = "带认证的邮件"
mail.Send
Set mail = Nothing
Set cfg = Nothing
%>smtpauthenticate = 1 is basic auth. Many providers require an app-specific password rather than the login password, and commonly use port 587 (STARTTLS) or 465 (SSL).
HTML 邮件与附件
<%
mail.Subject = "月度报告"
mail.HTMLBody = "<h1>月度报告</h1><p>详见附件。</p>"
mail.AddAttachment "C:\data\report.pdf"
mail.Send
%>Setting both TextBody and HTMLBody makes CDO build a multipart/alternative message, so text-only clients still see content. With only HTMLBody, text clients show a blank mail.
常见失败原因
| Symptom | Cause |
|---|---|
| CDO.Message 无法创建 | IIS SMTP 服务未安装,或 64 位/32 位不匹配 |
| Transport cannot connect | 端口被封、服务器地址错、未开 TLS |
| 550 relay denied | 发件人域名与认证账号不一致 |
| 中文主题乱码 | 未设置字符集 |
| 进入垃圾箱 | SPF / DKIM 未配 |
<%-- 中文主题需要显式编码 --%>
mail.Subject = "=?UTF-8?B?" & Base64Encode("月度报告") & "?=".asp hands it to anyone who can read the source, including an attacker exploiting a file-inclusion flaw. At minimum load it into Application from Global.asa, or use a local SMTP relay that needs no auth.在页面里同步发信的问题
mail.Send is synchronous: a slow SMTP server leaves the user staring at a spinner until timeout. Real projects write mail into a table and let a scheduled job send it; the page only enqueues.
最简单的发信
<%
Dim mail
Set mail = Server.CreateObject("CDO.Message")
mail.From = "noreply@example.com"
mail.To = "user@example.com"
mail.Subject = "注册确认"
mail.TextBody = "请点击链接完成注册。"
' 指定 SMTP 服务器
mail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
mail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.example.com"
mail.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
mail.Configuration.Fields.Update
mail.Send
Set mail = Nothing
Response.Write "邮件已发送"
%>邮件已发送sendusing = 2 表示走网络 SMTP(1 是投递到本地队列目录)。三个 configuration 字段必须写全,少一个就报「传输无法连接到服务器」。
需要认证的 SMTP
<%
Dim cfg, mail
Set cfg = Server.CreateObject("CDO.Configuration")
cfg.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
cfg.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.example.com"
cfg.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 587
cfg.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
cfg.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "apiuser"
cfg.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "secret"
cfg.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True
cfg.Fields.Update
Set mail = Server.CreateObject("CDO.Message")
Set mail.Configuration = cfg
mail.From = "noreply@example.com"
mail.To = "user@example.com"
mail.Subject = "测试"
mail.TextBody = "带认证的邮件"
mail.Send
Set mail = Nothing
Set cfg = Nothing
%>smtpauthenticate = 1 是基本认证。很多邮件服务商要求用「授权码」而不是登录密码,端口也常用 587(STARTTLS)或 465(SSL)。
HTML 邮件与附件
<%
mail.Subject = "月度报告"
mail.HTMLBody = "<h1>月度报告</h1><p>详见附件。</p>"
mail.AddAttachment "C:\data\report.pdf"
mail.Send
%>同时设 TextBody 和 HTMLBody 时,CDO 会自动生成 multipart/alternative——不支持 HTML 的客户端显示纯文本。只设 HTMLBody 时,纯文本客户端看到的是空邮件。
常见失败原因
| 现象 | 原因 |
|---|---|
| 组件创建失败 | IIS SMTP 服务未安装,或 64 位/32 位不匹配 |
| 连不上服务器 | 端口被封、服务器地址错、未开 TLS |
| 拒绝转发 | 发件人域名与认证账号不一致 |
| 主题乱码 | 未设置字符集 |
| 被判垃圾 | SPF / DKIM 未配 |
<%-- 中文主题需要显式编码 --%>
mail.Subject = "=?UTF-8?B?" & Base64Encode("月度报告") & "?=".asp 文件里,等于把密码给了任何能读源码的人(包括通过文件包含漏洞读到源码的攻击者)。至少放进 Application 由 Global.asa 初始化,或改用本地 SMTP 服务免认证投递。在页面里同步发信的问题
mail.Send 是同步的,SMTP 一慢,用户就要盯着转圈等到超时。正式项目应该把待发邮件写进数据库,由计划任务批量发送——页面只负责入队。