Blazor 客户端发送电子邮件

时间:2021-02-20 23:16:17

标签: c# email web blazor blazor-client-side

我在剃刀页面中包含了一个联系表单,因此用户可以用他的电子邮件、主题和正文填写它。当他提交时,电子邮件会发送到我的电子邮件地址。

我的代码看起来像这样 example

但是当我提交表单时,我遇到了这个错误

<块引用>

此平台不支持操作。

它不受支持,因为我在浏览器(客户端)上运行它。

我想知道是否有人作为这种情况的转机,而不使用 smtp 服务器(因为用户可以访问服务器的凭据)或

<块引用>

test@example.com

谢谢。

问候,萨米。

2 个答案:

答案 0 :(得分:1)

这是不可能的,因为浏览器有禁止发送电子邮件的安全限制。此限制并非来自 Blazor 或 ASP.NET Core。它也不适用于 JavaScript。或者至少没有可疑的hacks

我不建议使用像 smtp.js 这样试图解决这些限制的项目:他们通过使用服务器端 API 来做唯一合适的方法。 但是这里的问题是,您通过生成安全令牌至少向 smtp.js 公开这些凭据,他们将您的凭据存储在他们的服务器上,以便 API 可以获取当您从 JS 调用它们的 Email.send() 方法时调用它们。

为了安全地实现这一点,您需要在服务器端使用某种 API 来使用邮件服务器(主要使用 SMTP)发送这些邮件。既然你说它在浏览器上运行,我假设你正在使用 Blazor WebAssembly。因此,要么创建一个可以使用例如调用的 API 项目WASM 项目中的 Ajax 或切换到 Blazor Server which allows you to run the code directly on the server, if this is suiteable for the use-case

重要提示:注意滥用!

即使您自己的 API 使用秘密存储在您自己的服务器上的凭据,防止滥用也很重要。如果有一个 API 可以不受任何限制地向任何拥有您帐户的人发送邮件,那么机器人滥用它们发送垃圾邮件只是时间问题——即使凭据没有暴露!

这会在很多方面伤害您:

  • 名义的垃圾邮件甚至恶意内容
  • 您的邮件帐户已被关闭
  • 不会发送您想要的邮件,因为您的邮件在每个垃圾邮件列表中
  • ...

出于这个原因,您应该有兴趣仅从您的服务器发送邮件,并对该 API 进行适当限制,例如仅允许将发件人列入白名单、速率限制等。

答案 1 :(得分:1)

这篇博文可能对您有所帮助: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>