如何从 JavaScript 发送电子邮件

IT技术 javascript email
2021-01-28 04:15:26

我希望我的网站能够在不刷新页面的情况下发送电子邮件。所以我想使用Javascript。

<form action="javascript:sendMail();" name="pmForm" id="pmForm" method="post">
Enter Friend's Email:
<input name="pmSubject" id="pmSubject" type="text" maxlength="64" style="width:98%;" />
<input name="pmSubmit" type="submit" value="Invite" />

这是我想要调用该函数的方式,但我不确定该将什么放入 javascript 函数中。从我所做的研究中,我发现了一个使用 mailto 方法的示例,但我的理解是它实际上并不直接从站点发送。

所以我的问题是我在哪里可以找到在 JavaScript 函数中放置什么以直接从网站发送电子邮件。

function sendMail() {
    /* ...code here...    */
}
6个回答

您不能直接使用 javascript 发送电子邮件。

但是,您可以打开用户的邮件客户端:

window.open('mailto:test@example.com');

还有一些参数可以预填充主题和正文:

window.open('mailto:test@example.com?subject=subject&body=body');

另一种解决方案是对您的服务器进行 ajax 调用,以便服务器发送电子邮件。小心不要让任何人通过您的服务器发送任何电子邮件。

如果打开页面的程序已经具有电子邮件客户端功能..(如 Opera 12.50),那么它会将链接作为常规 URL 打开。他们还有 Thunderbird,它具有 firefox Gecko 引擎:它可以从电子邮件中的超链接作为新标签打开网页。
2021-03-16 04:15:26
我会更进一步,window.open( String( 'mailto:recipient^example.com' ).replace('^', '@') );混淆垃圾邮件机器人
2021-03-16 04:15:26
该答案确实没有回答问题,但@rahulroy 的答案很好
2021-03-19 04:15:26
请注意,您还可以使用window.location.href(例如在这个答案中:stackoverflow.com/questions/271171/...)打开电子邮件客户端,当用户完成电子邮件时,它不会留下那个空窗口。
2021-03-23 04:15:26
subjectbody变量或者是他们的实际文本,这将是在领域?
2021-04-02 04:15:26

间接通过您的服务器 - 调用 3rd Party API - 安全且推荐


您的服务器可以在正确的身份验证和授权后调用 3rd Party API。API 密钥不会向客户端公开。

node.js - https://www.npmjs.org/package/node-mandrill

const mandrill = require('node-mandrill')('<your API Key>'); 

function sendEmail ( _name, _email, _subject, _message) {
    mandrill('/messages/send', {
        message: {
            to: [{email: _email , name: _name}],
            from_email: 'noreply@yourdomain.com',
            subject: _subject,
            text: _message
        }
    }, function(error, response){
        if (error) console.log( error );
        else console.log(response);
    });
}

// define your own email api which points to your server.

app.post( '/api/sendemail/', function(req, res){
            
    let _name = req.body.name;
    let _email = req.body.email;
    let _subject = req.body.subject;
    let _messsage = req.body.message;

    //implement your spam protection or checks. 

    sendEmail ( _name, _email, _subject, _message );

});

然后在客户端使用 $.ajax 调用您的电子邮件 API。


直接从客户端 - 调用 3rd Party API - 不推荐


仅使用 JavaScript 发送电子邮件

简而言之:

  1. 注册 Mandrill 以获取 API 密钥
  2. 加载jQuery
  3. 使用 $.ajax 发送电子邮件

像这样 -

function sendMail() {
    $.ajax({
      type: 'POST',
      url: 'https://mandrillapp.com/api/1.0/messages/send.json',
      data: {
        'key': 'YOUR API KEY HERE',
        'message': {
          'from_email': 'YOUR@EMAIL.HERE',
          'to': [
              {
                'email': 'RECIPIENT@EMAIL.HERE',
                'name': 'RECIPIENT NAME (OPTIONAL)',
                'type': 'to'
              }
            ],
          'autotext': 'true',
          'subject': 'YOUR SUBJECT HERE!',
          'html': 'YOUR EMAIL CONTENT HERE! YOU CAN USE HTML!'
        }
      }
     }).done(function(response) {
       console.log(response); // if you're into that sorta thing
     });
}

https://medium.com/design-startups/b53319616782

注意:请记住,任何人都可以看到您的 API 密钥,因此任何恶意用户都可能使用您的密钥发送电子邮件,这可能会耗尽您的配额。

即使文章确实这么说,我觉得也应该在这里说,即使这会起作用,也存在一些安全问题,因为您还需要将 api 密钥发送给客户端。这可能会被滥用。
2021-03-14 04:15:26

我找不到真正满足原始问题的答案。

  • Mandrill 是不可取的,因为它是新的定价政策,而且如果你想保证你的凭证安全,它需要一个后端服务。
  • 通常最好隐藏您的电子邮件,这样您就不会出现在任何列表中(mailto 解决方案暴露了这个问题,对大多数用户来说并不方便)。
  • 设置 sendMail 或仅仅需要一个后端来发送电子邮件都很麻烦。

我整理了一个简单的免费服务,它允许您发出标准的 HTTP POST 请求来发送电子邮件。它称为PostMail,您可以简单地发布表单,使用 JavaScript 或 jQuery。当您注册时,它会为您提供代码,您可以将这些代码复制并粘贴到您的网站中。这里有些例子:

JavaScript:

<form id="javascript_form">
    <input type="text" name="subject" placeholder="Subject" />
    <textarea name="text" placeholder="Message"></textarea>
    <input type="submit" id="js_send" value="Send" />
</form>

<script>

    //update this with your js_form selector
    var form_id_js = "javascript_form";

    var data_js = {
        "access_token": "{your access token}" // sent after you sign up
    };

    function js_onSuccess() {
        // remove this to avoid redirect
        window.location = window.location.pathname + "?message=Email+Successfully+Sent%21&isError=0";
    }

    function js_onError(error) {
        // remove this to avoid redirect
        window.location = window.location.pathname + "?message=Email+could+not+be+sent.&isError=1";
    }

    var sendButton = document.getElementById("js_send");

    function js_send() {
        sendButton.value='Sending…';
        sendButton.disabled=true;
        var request = new XMLHttpRequest();
        request.onreadystatechange = function() {
            if (request.readyState == 4 && request.status == 200) {
                js_onSuccess();
            } else
            if(request.readyState == 4) {
                js_onError(request.response);
            }
        };

        var subject = document.querySelector("#" + form_id_js + " [name='subject']").value;
        var message = document.querySelector("#" + form_id_js + " [name='text']").value;
        data_js['subject'] = subject;
        data_js['text'] = message;
        var params = toParams(data_js);

        request.open("POST", "https://postmail.invotes.com/send", true);
        request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

        request.send(params);

        return false;
    }

    sendButton.onclick = js_send;

    function toParams(data_js) {
        var form_data = [];
        for ( var key in data_js ) {
            form_data.push(encodeURIComponent(key) + "=" + encodeURIComponent(data_js[key]));
        }

        return form_data.join("&");
    }

    var js_form = document.getElementById(form_id_js);
    js_form.addEventListener("submit", function (e) {
        e.preventDefault();
    });
</script>

jQuery:

<form id="jquery_form">
    <input type="text" name="subject" placeholder="Subject" />
    <textarea name="text" placeholder="Message" ></textarea>
    <input type="submit" name="send" value="Send" />
</form>

<script>

    //update this with your $form selector
    var form_id = "jquery_form";

    var data = {
        "access_token": "{your access token}" // sent after you sign up
    };

    function onSuccess() {
        // remove this to avoid redirect
        window.location = window.location.pathname + "?message=Email+Successfully+Sent%21&isError=0";
    }

    function onError(error) {
        // remove this to avoid redirect
        window.location = window.location.pathname + "?message=Email+could+not+be+sent.&isError=1";
    }

    var sendButton = $("#" + form_id + " [name='send']");

    function send() {
        sendButton.val('Sending…');
        sendButton.prop('disabled',true);

        var subject = $("#" + form_id + " [name='subject']").val();
        var message = $("#" + form_id + " [name='text']").val();
        data['subject'] = subject;
        data['text'] = message;

        $.post('https://postmail.invotes.com/send',
            data,
            onSuccess
        ).fail(onError);

        return false;
    }

    sendButton.on('click', send);

    var $form = $("#" + form_id);
    $form.submit(function( event ) {
        event.preventDefault();
    });
</script>

同样,完全公开,我创建此服务是因为我找不到合适的答案。

这不是和其他人有同样的问题吗?访问令牌(API Key)暴露
2021-03-15 04:15:26
这是最好的解决方案。非常感谢。Mandrill 不再有免费计划,并且 mailgun 不支持 cors,因此不支持 JavaScript
2021-03-18 04:15:26
我一直在寻找这个解决方案,感谢您的回答,但我想知道如何在 html 表单中再添加一个文本框,因为每当我尝试更改代码以添加另一个文本框以获取其他信息时,代码就会停止在职的。你知道有什么解决办法吗。
2021-03-20 04:15:26
他们每天限制为 25 封电子邮件。
2021-03-20 04:15:26
现在应该备份了。对于那个很抱歉!
2021-03-24 04:15:26

我知道我太晚了,无法为这个问题写答案,但我认为这将适用于任何想通过 javascript 发送电子邮件的人。

我建议的第一种方法是使用回调在服务器上执行此操作。如果您真的希望使用 javascript 来处理它,那么我建议您这样做。

我发现的最简单的方法是使用 smtpJs。可用于发送电子邮件的免费库。

1.包含如下脚本

<script src="https://smtpjs.com/v3/smtp.js"></script>

2.您可以发送这样的电子邮件

Email.send({
    Host : "smtp.yourisp.com",
    Username : "username",
    Password : "password",
    To : 'them@website.com',
    From : "you@isp.com",
    Subject : "This is the subject",
    Body : "And this is the body"
    }).then(
      message => alert(message)
    );

这是不可取的,因为它会在客户端显示您的密码。因此,您可以执行以下操作,加密您的 SMTP 凭据,并将其锁定到单个域,并传递安全令牌而不是凭据。

Email.send({
    SecureToken : "C973D7AD-F097-4B95-91F4-40ABC5567812",
    To : 'them@website.com',
    From : "you@isp.com",
    Subject : "This is the subject",
    Body : "And this is the body"
}).then(
  message => alert(message)
);

最后,如果您没有 SMTP 服务器,您可以使用 smtp 中继服务,例如Elastic Email

此外,这里是SmtpJS.com官方网站的链接,您可以在其中找到所需的所有示例以及可以创建安全令牌的位置。

我希望有人觉得这个细节有用。快乐编码。

错误是Uncaught ReferenceError: Email is not defined预期的吗?我很确定你没有定义Email. 还是您使用了代码片段而不仅仅是代码围栏,而我们不应该运行它?另外我认为你还不算太晚。
2021-03-16 04:15:26
SecureToken 只对创建时指定的域有效,因此从其他域调用 js 将不起作用。
2021-03-21 04:15:26
这仍然允许第三方完全访问您的 SMTP 服务器,以便他们可以为您中继邮件以换取……什么?
2021-03-26 04:15:26
@smoore4 是的,但他们仍然必须在他们的服务器上解密它,并且他们可以访问您的密码和其他东西。我不会相信这项服务。
2021-03-28 04:15:26
最安全和唯一的方法是托管您自己的服务
2021-04-01 04:15:26

您可以在这篇文章中找到要放入 JavaScript 函数的内容。

function getAjax() {
    try {
        if (window.XMLHttpRequest) {
            return new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            try {
                return new ActiveXObject('Msxml2.XMLHTTP');
            } catch (try_again) {
                return new ActiveXObject('Microsoft.XMLHTTP');
            }
        }
    } catch (fail) {
        return null;
    }
}

function sendMail(to, subject) {
     var rq = getAjax();

     if (rq) {
         // Success; attempt to use an Ajax request to a PHP script to send the e-mail
         try {
             rq.open('GET', 'sendmail.php?to=' + encodeURIComponent(to) + '&subject=' + encodeURIComponent(subject) + '&d=' + new Date().getTime().toString(), true);

             rq.onreadystatechange = function () {
                 if (this.readyState === 4) {
                     if (this.status >= 400) {
                         // The request failed; fall back to e-mail client
                         window.open('mailto:' + to + '?subject=' + encodeURIComponent(subject));
                     }
                 }
             };

             rq.send(null);
         } catch (fail) {
             // Failed to open the request; fall back to e-mail client
             window.open('mailto:' + to + '?subject=' + encodeURIComponent(subject));
         }
     } else {
         // Failed to create the request; fall back to e-mail client
         window.open('mailto:' + to + '?subject=' + encodeURIComponent(subject));
     }
}

提供您自己的 PHP(或任何语言)脚本来发送电子邮件。