使用 Javascript 在 Microsoft Outlook 中创建 HTML 电子邮件
Use Javascript to create an HTML email in Microsoft Outlook
我想从 Javascript 网络应用程序创建电子邮件。我完全了解关于此的许多 SO 问题(例如 Open Outlook HTML with Chrome)。典型答案有问题:
Mailto:link:这将允许您创建电子邮件,但只能是纯文本格式(没有 HTML)并且不允许附件。
Activex:仅限 IE,我的应用程序需要在 Firefox 中 运行 和 Chrome。 FF 和 Chrome 允许 ActiveX 的插件是安全隐患,而且似乎有问题。
服务器端通过 SMTP 发送:电子邮件不会在用户的 "Sent" 文件夹中结束。加上允许用户在浏览器中编辑 HTML 和附加文件的障碍。
创建一个 Outlook .MSG 文件:似乎没有库,而且很少有人写过这样做。显然,该文件格式实际上嵌入了整个 FAT 文件存储系统。
许多其他 SO 问题和我的问题之间的主要区别:
- 我可以访问客户端机器,所以我可以安装
帮助应用程序或加载项,根据需要更改设置等。
- 接口不需要实际发送邮件,只需要
为用户设置它。
- 我还需要能够为电子邮件提供 JS 附件(例如 PDF)。
我不是第一个遇到这个问题的网络应用程序开发人员,但我找不到商业或开源解决方案。
更新:
我使用了 EML 文件方法,到目前为止效果很好。这是我创建和触发它的 JS 代码:
var emlContent = "data:message/rfc822 eml;charset=utf-8,";
emlContent += 'To: '+emailTo+'\n';
emlContent += 'Subject: '+emailSubject+'\n';
emlContent += 'X-Unsent: 1'+'\n';
emlContent += 'Content-Type: text/html'+'\n';
emlContent += ''+'\n';
emlContent += htmlDocument;
var encodedUri = encodeURI(emlContent); //encode spaces etc like a url
var a = document.createElement('a'); //make a link in document
var linkText = document.createTextNode("fileLink");
a.appendChild(linkText);
a.href = encodedUri;
a.id = 'fileLink';
a.download = 'filename.eml';
a.style = "display:none;"; //hidden link
document.body.appendChild(a);
document.getElementById('fileLink').click(); //click the link
MSG文件格式是documented,不过肯定不好玩...
为什么不创建 EML (MIME) 文件?
建议使用 EML (MIME) 格式。根据 OP,他们考虑了 MSG 文件格式(#4),但由于复杂性或缺乏处理该格式的 JS 库而被劝阻。如果考虑 MSG 文件,MIME 是更好的选择 - 它是基于文本的,因此不需要特殊的库来创建它。 Outlook 将能够像打开 MSG 文件一样轻松地打开它。
要确保它被 Outlook 视为未发送的邮件,请将 X-Unsent
MIME header 设置为 1。
最简单的 EML 文件如下所示:
To: Joe The User <joe@domain.demo>
Subject: Test EML message
X-Unsent: 1
Content-Type: text/html
<html>
<body>
Test message with <b>bold</b> text.
</body>
</html>
利用纯文本 eml 文件的想法,我想出了这个:http://jsfiddle.net/CalvT/un3hapej/
这是对我发现的东西的编辑 - 创建一个 .txt
文件然后下载它。由于 .eml
文件实际上是 .txt 文件,我认为这可行。确实如此。我已将示例电子邮件留在 textarea
中,以便您轻松测试。当您单击创建文件时,它会为您提供下载 link 以下载您的 .eml
文件。我能看到的唯一障碍是让浏览器在下载后打开 .eml
文件。
编辑:考虑一下,当您可以访问客户端计算机时,您可以将浏览器设置为始终打开该类型的文件。例如在 Chrome 中,您可以单击下载旁边的箭头,然后 select 总是打开这种类型的文件。
这是代码
HTML:
(function () {
var textFile = null,
makeTextFile = function (text) {
var data = new Blob([text], {type: 'text/plain'});
if (textFile !== null) {
window.URL.revokeObjectURL(textFile);
}
textFile = window.URL.createObjectURL(data);
return textFile;
};
var create = document.getElementById('create'),
textbox = document.getElementById('textbox');
create.addEventListener('click', function () {
var link = document.getElementById('downloadlink');
link.href = makeTextFile(textbox.value);
link.style.display = 'block';
}, false);
})();
<textarea id="textbox" style="width: 300px; height: 200px;">
To: User <user@domain.demo>
Subject: Subject
X-Unsent: 1
Content-Type: text/html
<html>
<body>
Test message
</body>
</html>
</textarea>
<button id="create">Create file</button>
<a download="message.eml" id="downloadlink" style="display: none">Download</a>
似乎没有人回答附件问题,所以这是我的解决方案:
将 EML 创建为 multipart/mixed 消息。
Content-Type: multipart/mixed; boundary=--boundary_text_string
这样,您的电子邮件中就可以包含多个部分。
多个部分让您可以添加附件,就像这样。
Content-Type: application/octet-stream; name=demo.pdf
Content-Transfer-Encoding: base64
Content-Disposition: attachment
从您的电子邮件 headers 开始,然后添加您的边界,然后是部分内容(换行符位置非常重要,否则客户将无法正确解析您的文件)。您可以添加多个部分。下面是一个例子。请注意,最后一个边界与其他边界不同(末尾有 2 个破折号)。
To: Demo-Recipient <demo@demo.example.com>
Subject: EML with attachments
X-Unsent: 1
Content-Type: multipart/mixed; boundary=--boundary_text_string
----boundary_text_string
Content-Type: text/html; charset=UTF-8
<html>
<body>
<p>Example</p>
</body>
</html>
----boundary_text_string
Content-Type: application/octet-stream; name=demo.txt
Content-Transfer-Encoding: base64
Content-Disposition: attachment
ZXhhbXBsZQ==
----boundary_text_string
Content-Type: application/octet-stream; name=demo.log
Content-Transfer-Encoding: base64
Content-Disposition: attachment
ZXhhbXBsZQ==
----boundary_text_string--
这会为您提供一个带有两个附件的 eml 文件。
如果您想了解有关其工作原理的更多细节,请参阅 RFC 1371。
我在创建包含 non-english 个字符的 .eml 文件然后在 Outlook 中打开它时遇到编码问题。
问题是我把“charset=”放在了错误的地方,并且没有在编码周围加上引号 (")。
解决方案:
function createShiftReportEmail() {
const title = "Shift Összefoglaló";
const body = "ÁÉŐÚŰÓÜÖÍűáéúőóöí";
const emlContent = new Blob([`data:message/rfc822 eml,\nSubject: ${title}\nX-Unsent: 1\nContent-Type: text/plain;charset="utf-8"\n\n${body}`]);
if (!document.querySelector('#downloadEmail')) {
document.body.insertAdjacentHTML('beforeend', '<a id="downloadEmail" download="ShiftReport.eml" style="display: none">Download</a>');
}
const downloadBtn = document.querySelector('#downloadEmail');
downloadBtn.href = URL.createObjectURL(emlContent);
downloadBtn.click();
}
编辑:原来甚至不需要引号 (")。只是位置对我来说是错误的。
我想从 Javascript 网络应用程序创建电子邮件。我完全了解关于此的许多 SO 问题(例如 Open Outlook HTML with Chrome)。典型答案有问题:
Mailto:link:这将允许您创建电子邮件,但只能是纯文本格式(没有 HTML)并且不允许附件。
Activex:仅限 IE,我的应用程序需要在 Firefox 中 运行 和 Chrome。 FF 和 Chrome 允许 ActiveX 的插件是安全隐患,而且似乎有问题。
服务器端通过 SMTP 发送:电子邮件不会在用户的 "Sent" 文件夹中结束。加上允许用户在浏览器中编辑 HTML 和附加文件的障碍。
创建一个 Outlook .MSG 文件:似乎没有库,而且很少有人写过这样做。显然,该文件格式实际上嵌入了整个 FAT 文件存储系统。
许多其他 SO 问题和我的问题之间的主要区别:
- 我可以访问客户端机器,所以我可以安装 帮助应用程序或加载项,根据需要更改设置等。
- 接口不需要实际发送邮件,只需要 为用户设置它。
- 我还需要能够为电子邮件提供 JS 附件(例如 PDF)。
我不是第一个遇到这个问题的网络应用程序开发人员,但我找不到商业或开源解决方案。
更新:
我使用了 EML 文件方法,到目前为止效果很好。这是我创建和触发它的 JS 代码:
var emlContent = "data:message/rfc822 eml;charset=utf-8,";
emlContent += 'To: '+emailTo+'\n';
emlContent += 'Subject: '+emailSubject+'\n';
emlContent += 'X-Unsent: 1'+'\n';
emlContent += 'Content-Type: text/html'+'\n';
emlContent += ''+'\n';
emlContent += htmlDocument;
var encodedUri = encodeURI(emlContent); //encode spaces etc like a url
var a = document.createElement('a'); //make a link in document
var linkText = document.createTextNode("fileLink");
a.appendChild(linkText);
a.href = encodedUri;
a.id = 'fileLink';
a.download = 'filename.eml';
a.style = "display:none;"; //hidden link
document.body.appendChild(a);
document.getElementById('fileLink').click(); //click the link
MSG文件格式是documented,不过肯定不好玩... 为什么不创建 EML (MIME) 文件?
建议使用 EML (MIME) 格式。根据 OP,他们考虑了 MSG 文件格式(#4),但由于复杂性或缺乏处理该格式的 JS 库而被劝阻。如果考虑 MSG 文件,MIME 是更好的选择 - 它是基于文本的,因此不需要特殊的库来创建它。 Outlook 将能够像打开 MSG 文件一样轻松地打开它。
要确保它被 Outlook 视为未发送的邮件,请将 X-Unsent
MIME header 设置为 1。
最简单的 EML 文件如下所示:
To: Joe The User <joe@domain.demo>
Subject: Test EML message
X-Unsent: 1
Content-Type: text/html
<html>
<body>
Test message with <b>bold</b> text.
</body>
</html>
利用纯文本 eml 文件的想法,我想出了这个:http://jsfiddle.net/CalvT/un3hapej/
这是对我发现的东西的编辑 - 创建一个 .txt
文件然后下载它。由于 .eml
文件实际上是 .txt 文件,我认为这可行。确实如此。我已将示例电子邮件留在 textarea
中,以便您轻松测试。当您单击创建文件时,它会为您提供下载 link 以下载您的 .eml
文件。我能看到的唯一障碍是让浏览器在下载后打开 .eml
文件。
编辑:考虑一下,当您可以访问客户端计算机时,您可以将浏览器设置为始终打开该类型的文件。例如在 Chrome 中,您可以单击下载旁边的箭头,然后 select 总是打开这种类型的文件。
这是代码
HTML:
(function () {
var textFile = null,
makeTextFile = function (text) {
var data = new Blob([text], {type: 'text/plain'});
if (textFile !== null) {
window.URL.revokeObjectURL(textFile);
}
textFile = window.URL.createObjectURL(data);
return textFile;
};
var create = document.getElementById('create'),
textbox = document.getElementById('textbox');
create.addEventListener('click', function () {
var link = document.getElementById('downloadlink');
link.href = makeTextFile(textbox.value);
link.style.display = 'block';
}, false);
})();
<textarea id="textbox" style="width: 300px; height: 200px;">
To: User <user@domain.demo>
Subject: Subject
X-Unsent: 1
Content-Type: text/html
<html>
<body>
Test message
</body>
</html>
</textarea>
<button id="create">Create file</button>
<a download="message.eml" id="downloadlink" style="display: none">Download</a>
似乎没有人回答附件问题,所以这是我的解决方案: 将 EML 创建为 multipart/mixed 消息。
Content-Type: multipart/mixed; boundary=--boundary_text_string
这样,您的电子邮件中就可以包含多个部分。 多个部分让您可以添加附件,就像这样。
Content-Type: application/octet-stream; name=demo.pdf
Content-Transfer-Encoding: base64
Content-Disposition: attachment
从您的电子邮件 headers 开始,然后添加您的边界,然后是部分内容(换行符位置非常重要,否则客户将无法正确解析您的文件)。您可以添加多个部分。下面是一个例子。请注意,最后一个边界与其他边界不同(末尾有 2 个破折号)。
To: Demo-Recipient <demo@demo.example.com>
Subject: EML with attachments
X-Unsent: 1
Content-Type: multipart/mixed; boundary=--boundary_text_string
----boundary_text_string
Content-Type: text/html; charset=UTF-8
<html>
<body>
<p>Example</p>
</body>
</html>
----boundary_text_string
Content-Type: application/octet-stream; name=demo.txt
Content-Transfer-Encoding: base64
Content-Disposition: attachment
ZXhhbXBsZQ==
----boundary_text_string
Content-Type: application/octet-stream; name=demo.log
Content-Transfer-Encoding: base64
Content-Disposition: attachment
ZXhhbXBsZQ==
----boundary_text_string--
这会为您提供一个带有两个附件的 eml 文件。 如果您想了解有关其工作原理的更多细节,请参阅 RFC 1371。
我在创建包含 non-english 个字符的 .eml 文件然后在 Outlook 中打开它时遇到编码问题。 问题是我把“charset=”放在了错误的地方,并且没有在编码周围加上引号 (")。 解决方案:
function createShiftReportEmail() {
const title = "Shift Összefoglaló";
const body = "ÁÉŐÚŰÓÜÖÍűáéúőóöí";
const emlContent = new Blob([`data:message/rfc822 eml,\nSubject: ${title}\nX-Unsent: 1\nContent-Type: text/plain;charset="utf-8"\n\n${body}`]);
if (!document.querySelector('#downloadEmail')) {
document.body.insertAdjacentHTML('beforeend', '<a id="downloadEmail" download="ShiftReport.eml" style="display: none">Download</a>');
}
const downloadBtn = document.querySelector('#downloadEmail');
downloadBtn.href = URL.createObjectURL(emlContent);
downloadBtn.click();
}
编辑:原来甚至不需要引号 (")。只是位置对我来说是错误的。