Blazor 客户端发送电子邮件
Blazor client side send an email
我在 razor 页面中包含了一个联系表单,因此用户可以在其中填写他的电子邮件、主题和正文。当他提交时,电子邮件会发送到我的电子邮件地址。
我的代码如下所示example
但是当我提交表单时,出现了这个错误
Operation is not supported on this platform.
它不受支持,因为我 运行 它在浏览器(客户端)上。
我想知道是否有人可以解决这种情况,不使用 smtp 服务器(因为用户可以访问服务器的凭据)或
test@example.com
谢谢。
此致,萨米赫。
这是不可能的,因为浏览器有禁止发送电子邮件的安全限制。此限制并非来自 Blazor 或 ASP.NET Core。它也不适用于 JavaScript。或者至少不是有问题的 hacks.
我不建议使用像 smtp.js 这样试图解决这些限制的项目:他们正在通过使用服务器端 API 来做唯一合适的方法。 但是这里的问题是,您至少将这些凭据公开给 smtp.js 因为通过生成安全令牌,他们将您的凭据存储在 他们的服务器上 所以当你从 JS 调用它们的 Email.send()
方法时 API 可以获取它们。
为了安全地实现这一点,您需要在服务器端使用某种 API 来使用邮件服务器(主要使用 SMTP)发送这些邮件。既然你说它在浏览器上运行,我假设你使用的是 Blazor WebAssembly。因此,要么创建一个 API 项目,可以使用例如调用Ajax 从您的 WASM 项目或切换到 .
重要提示:注意误用!
即使使用您自己的 API 使用秘密存储在您自己的服务器上的凭据,防止滥用也很重要。如果有一个 API 可以无限制地向任何拥有您帐户的人发送邮件,那么机器人滥用它们发送垃圾邮件只是时间问题 - 即使没有暴露凭据!
这会在很多方面伤害您:
- 您姓名中的垃圾邮件甚至恶意内容
- 您的邮件帐户已被删除
- 无法发送所需的邮件,因为您的邮件在每个垃圾邮件列表中
- ...
出于这个原因,只从您的服务器发送邮件并适当限制 API 应该符合您的利益,例如只允许白名单发件人、速率限制等。
此博客 post 可能对您有所帮助:Blazor (Wasm) – How to Send Email from a PWA。它调用用户的本机邮件应用程序,而不是依赖基于服务器或基于 API 的实现。
摘录,“...对于非常基本的电子邮件需求,是利用使用“mailto:”锚链接的老派技术,结合注入 Blazor 的 IJSRuntime。“
protected void SendLocalEmail(string toEmailAddress, string subject, string body)
{
JsRuntime.InvokeAsync<object>("blazorExtensions.SendLocalEmail",
new object[] { toEmailAddress, subject, body });
}
然后,在您的 wwwroot 文件夹中,您应该有一个相应的 .js 文件(即 GlobalFunctions.js),其中包含相应的 JavaScript SendLocalEmail() 函数
window.blazorExtensions = {
SendLocalEmail: function (mailto, subject, body) {
var link = document.createElement('a');
var uri = "mailto:" + mailto + "?";
if (!isEmpty(subject)) {
uri = uri + "subject=" + subject;
}
if (!isEmpty(body)) {
if (!isEmpty(subject)) { // We already appended one querystring parameter, add the '&' separator
uri = uri + "&"
}
uri = uri + "body=" + body;
}
uri = encodeURI(uri);
uri = uri.substring(0, 2000); // Avoid exceeding querystring limits.
console.log('Clicking SendLocalEmail link:', uri);
link.href = uri;
document.body.appendChild(link); // Needed for Firefox
link.click();
document.body.removeChild(link);
}
};
function isEmpty(str) {
return (!str || str.length === 0);
}
最后,确保在 index.html 文件(也在 wwwroot 文件夹中)中包含对 .js 文件的引用:
<script src="GlobalFunctions.js"></script>
我将上面的脚本引用放在这一行下面:
<script>navigator.serviceWorker.register('service-worker.js');</script>
我在 razor 页面中包含了一个联系表单,因此用户可以在其中填写他的电子邮件、主题和正文。当他提交时,电子邮件会发送到我的电子邮件地址。
我的代码如下所示example
但是当我提交表单时,出现了这个错误
Operation is not supported on this platform.
它不受支持,因为我 运行 它在浏览器(客户端)上。
我想知道是否有人可以解决这种情况,不使用 smtp 服务器(因为用户可以访问服务器的凭据)或
test@example.com
谢谢。
此致,萨米赫。
这是不可能的,因为浏览器有禁止发送电子邮件的安全限制。此限制并非来自 Blazor 或 ASP.NET Core。它也不适用于 JavaScript。或者至少不是有问题的 hacks.
我不建议使用像 smtp.js 这样试图解决这些限制的项目:他们正在通过使用服务器端 API 来做唯一合适的方法。 但是这里的问题是,您至少将这些凭据公开给 smtp.js 因为通过生成安全令牌,他们将您的凭据存储在 他们的服务器上 所以当你从 JS 调用它们的 Email.send()
方法时 API 可以获取它们。
为了安全地实现这一点,您需要在服务器端使用某种 API 来使用邮件服务器(主要使用 SMTP)发送这些邮件。既然你说它在浏览器上运行,我假设你使用的是 Blazor WebAssembly。因此,要么创建一个 API 项目,可以使用例如调用Ajax 从您的 WASM 项目或切换到
重要提示:注意误用!
即使使用您自己的 API 使用秘密存储在您自己的服务器上的凭据,防止滥用也很重要。如果有一个 API 可以无限制地向任何拥有您帐户的人发送邮件,那么机器人滥用它们发送垃圾邮件只是时间问题 - 即使没有暴露凭据!
这会在很多方面伤害您:
- 您姓名中的垃圾邮件甚至恶意内容
- 您的邮件帐户已被删除
- 无法发送所需的邮件,因为您的邮件在每个垃圾邮件列表中
- ...
出于这个原因,只从您的服务器发送邮件并适当限制 API 应该符合您的利益,例如只允许白名单发件人、速率限制等。
此博客 post 可能对您有所帮助:Blazor (Wasm) – How to Send Email from a PWA。它调用用户的本机邮件应用程序,而不是依赖基于服务器或基于 API 的实现。
摘录,“...对于非常基本的电子邮件需求,是利用使用“mailto:”锚链接的老派技术,结合注入 Blazor 的 IJSRuntime。“
protected void SendLocalEmail(string toEmailAddress, string subject, string body)
{
JsRuntime.InvokeAsync<object>("blazorExtensions.SendLocalEmail",
new object[] { toEmailAddress, subject, body });
}
然后,在您的 wwwroot 文件夹中,您应该有一个相应的 .js 文件(即 GlobalFunctions.js),其中包含相应的 JavaScript SendLocalEmail() 函数
window.blazorExtensions = {
SendLocalEmail: function (mailto, subject, body) {
var link = document.createElement('a');
var uri = "mailto:" + mailto + "?";
if (!isEmpty(subject)) {
uri = uri + "subject=" + subject;
}
if (!isEmpty(body)) {
if (!isEmpty(subject)) { // We already appended one querystring parameter, add the '&' separator
uri = uri + "&"
}
uri = uri + "body=" + body;
}
uri = encodeURI(uri);
uri = uri.substring(0, 2000); // Avoid exceeding querystring limits.
console.log('Clicking SendLocalEmail link:', uri);
link.href = uri;
document.body.appendChild(link); // Needed for Firefox
link.click();
document.body.removeChild(link);
}
};
function isEmpty(str) {
return (!str || str.length === 0);
}
最后,确保在 index.html 文件(也在 wwwroot 文件夹中)中包含对 .js 文件的引用:
<script src="GlobalFunctions.js"></script>
我将上面的脚本引用放在这一行下面:
<script>navigator.serviceWorker.register('service-worker.js');</script>