整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

仅需 5 步,用 JavaScript 直接通过前端发送电子邮件

者 | Mateusz Iwaniuk

译者 | 明明如月,责编 | 夕颜

出品 | CSDN(ID:CSDNnews)

文章配套代码: https://github.com/iwaniukooo11/email-sender

现在,即使是创建最基本的网站,程序员也必须使用现代的功能和技术。甚至像为你的朋友创建简单的投资组合这样的基本项目也可能涉及到一些问题,比如从联系人表单接收数据。有很多方法可以读取这些数据。你可以将表单与数据库连接起来,然后从数据库中读取传入的消息来实现功能,但这样做会给不懂技术的客户造成困难。

你为什么不通过发送电子邮件传输信息?

不使用数据库就能接收到传入的消息,绝对是最佳选择,也是最方便用户的选择。但问题来了—如何实现呢?你可能认为需要使用某种后端语言。

实际上,你不必使用任何如 php 或 python 这种后端语言,你甚至不需要用到 node.js!你需要的就是一个简单的EmailJS 库。

本文将介绍下面两个重要功能:

  • 配置 emailjs 帐户

  • 使用 JS 发送电子邮件

请注意,在我的项目中,我使用了 gulp 和 webpack,我在 src 文件夹存放源码,dist 存放最终发布版本的代码。

我将分 5 个步骤向你展示如何从头开始构建电子邮件发送器。

步骤1-用 HTML 创建表单

首先需要创建一个 HTML 表单。你不必放置像 required 或 max 这种验证属性,因为稍后,preventDefault 函数将在你的提交事件上运行,它会让这些属性的处理失效。

表单中最重要的是为每个输入放置 name 属性,后面会用到。

我的非常简单的表单是这样的:

src/html/index.html

 <form class="form"> <input name='name' type="text" placeholder="Your name..." class="form__input" /> <input name='topic' type="text" placeholder="Topic..." class="form__input" /> <textarea name='message' type="text" placeholder="Your Message..." class="form__input" ></textarea>

<input type="submit" value="send" class="form__input form__input--button"> </form>

步骤2-注册成为 email 用户

要配置你的电子邮件,你必须注册电子邮件服务。别担心—使用这个网站非常方便和省时。

登入后,系统会询问你的电子邮件服务,它位于个人电子邮件服务区(personal email service)。在我的例子中,我选择了 gmail。

然后,你需要连接你的 gmail 帐户。这将用来发送电子邮件给你客户。例如,如果你关联了 xyz@gmail.com 账户,你后续发送的邮件都将从这个邮箱发出。所以不要担心“ Send email on your behalf” 这个授权信息—这正是你需要的!

连接完 gmail 账户后,点击添加服务(add service)按钮。

步骤3-创建邮件模板

如果你已经成功连接了你的 gmail 账户,你现在应该在信息中心中。现在需要创建电子邮件模板了。

切换到电子邮件模板卡,并单击创建一个新的模板(create a new template)。界面非常友好,所以创建模板不会有任何问题。

你可以选择模板的名称和 ID。我称之为“我的神奇模板(my_amazing_template)”。

接下来,你必须指定邮件的内容。

模板的变量值来自 input 中的 `name` 属性。你已将变量插入`{{{}}}`符号中。

不要忘记在“收件人”部分 (右侧) 添加电子邮件地址。你的电子邮件将被发送到该电子邮件地址上。截图中的收件人邮箱是我自己的公司邮箱。

这是我的简单模板,它使用来自 HTML 表单里的 3 个变量。我还指定了接收电子邮件的主题。

步骤4-保存 API 密钥

这部分没什么特别的。Emailjs 共享授权 API 密钥,将在发送电子邮件时使用。当然,放这些钥匙最好的地方是`.env` 配置。但是因为我使用的是简单的静态文件,我不想使用服务器配置,所以我将它们保存在 apikeys 文件中,然后再将它们导入。

你的 USER_ID 位于 Account > API Keys 菜单下。

TEMPLATE_ID 位于模板的标题下面。

这是我基于不存在的 keyssrc / js / apikeys. js 的示例配置.

src/js/apikeys.js

export default { USER_ID :'user_DPUd-rest-of-my-id', TEMPLATE_ID:'my_amazing_template'}

如果需要将源码发布到 GITHUB,不要忘记将 APIKEYS 文件添加到 .GITIGNORE文件中

步骤5-发送电子邮件

现在是该项目最后也是最重要的部分的了。现在我们必须使用 javascript 发送电子邮件。

首先,你必须下载 emailjs 包。

npm i emails-com

然后,转到 js 文件,导入库和 apikeys。

src/js/main.js

import emailjs from 'emailjs-com'import apiKeys from './apikeys'

现在是编写发送电子邮件功能的时候了

src/js/main.js

const sendEmail = e => { e.preventDefault

emailjs .sendForm('gmail', apiKeys.TEMPLATE_ID, e.target, apiKeys.USER_ID) .then( result => { console.log(result.text) }, error => { console.log(error.text) } )}

sendForm 函数有4个参数:

你的电子邮件的 ID,在这里:

TEMPLATE_ID 来自 apikey 文件,

事件对象来自你的表单提交

USER_ID 来自 apikey 文件,

最后,查找表单并添加提交事件监听器:

src/js/main.js

const form = document.querySelector('.form')form.addEventListener('submit',sendEmail)

正如我前面提到的,由于 `preventDefault` 函数,属性验证将无法工作。你必须使用 JS 自己进行验证和清除输入。

以上就是全部内容,接下来让我们测试一下。

填写页面上的表单并发送。

我收到电子邮件,内容正是根据我们的模板和表单数据渲染出来的。

通过上图可以看出,所有的变量的值都填充到了正确的位置上。

总结

通过本文的介绍你会发现用 JS 发送邮件并非难事。

使用 emailjs,你可以简单的方式发送电子邮件。

我相信你未来的用户会很高兴收到来自他们网页上表单填写数据的t邮件,相信本文对你有帮助。

这篇文章的配套代码在这里: https://github.com/iwaniukooo11/email-sender

原文链接:

https://dev.to/iwaniukooo11/send-e-mails-directly-from-front-end-with-js-5d7d

本文为CSDN翻译文章,转载请注明出处。

☞我们想研发一个机器学习框架,6 个月后失败了

☞生产型机器学习已经没那么困难了?

☞视频 | 你不知道的"开源"60年秘史

☞GitHub标星10,000+,Apache项目ShardingSphere的开源之路

☞阿里技术专家告诉你,如何画出优秀的架构图?

☞加拿大API平台如何做到30%为中国明星项目?创业老兵这样说……

常生活工作学习中,大家对电子表格必定不陌生。从工作数据汇总分析到出门收据各种电子发票,这些都是由电子表格制作出来的。

不过大家对电子表格的印象可能停留在这里:

标准行列数据统计的表格样式。但其实,表格也可以是这样的:

工作中遇到需要实现的表格情况往往比大家想象的要更加复杂,最近我们在做客户支持的工作过程中遇到了一个客户,他需要借助电子表格表格实现合同中的电子签名。

电子签名通俗来说就是通过技术手段实现在电子文档上加载电子形式的签名,其作用类似于纸质合同上的手写签名或加盖的公章。在企业工作流审批、请柬、单据保全等场景应用广泛。

在经济活跃跨区域化现象越来越多的今天,作为电子表格的一个重要使用场景,电子合同可以实现异地签约,签署的时间第点更加自由;面对大批量的合同签署也可以轻松解决;同时传统纸质合同的管理更加方便,避免了纸质合同因保存管理问题而出现损坏。

而今天,客户在实际项目中需要实现的内容长这样:

看到这里,有些小伙伴可能会说这有什么难的,虽然这个东西长相酷似word,

但不就是电子表格去掉边框线吗?

如果只是简单的表格框内容,下段代码就可以简单的实现表格的绘制。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>02Canvas案例-绘制表格</title>
</head>
<body>
<div id="container">
    <canvas id="cavsElem">
        
    </canvas>
</div>
<script>
    (function(){
        var canvas=document.querySelector('#cavsElem');
        var ctx=canvas.getContext('2d');
        canvas.width=600;
        canvas.height=600;
        canvas.style.border='1px solid green';
        var rectH=10;
        var rectW=20;
        ctx.lineWidth=.5;
        //绘制表格
        // 第一步: 绘制横线
        for(var i=0;i<canvas.width;i++){
            ctx.moveTo(rectW*i,0);
            //如果不设置moveTo,当前画笔没有位置
            ctx.lineTo(rectW*i,canvas.height);
        }
        //第二步:绘制竖线:如果绘制的格子的宽高相等,可以将for循环放到一个里面;
        for(var i=0;i<canvas.height;i++){
            ctx.moveTo(0,rectH*i);
            ctx.lineTo(canvas.width,rectH*i);
        }
        ctx.stroke();
    }())
</script>
</body>
</html>

但是放大仔细看看,就会发现情况并不如我们所想的这么简单。

在这个合同中,我们除了要隐藏边框线,还要考虑边缘留白、图片跨越、页面滚动后截图不全等问题。 而借助电子表格在数据处理和分析方面天生具备的优势,可以很容易的实现电子签名功能。

我们今天就一起来尝试通过基于Canvas的电子表格来实现电子签名并导出PDF的项目开发需求。

环境准备

  1. 环境准备:安装SpreadJS 前端表格插件,并通过插件绘制canvas画布。

2. 初始化Spread工作簿,并导入合同模板

3. 创建Canvas画布并引用esign.js画法实现手写签名区域

4. 通过自定义超链接跳转命令,签名区域呼出

5. 将签名区域转化为图片设置为背景图片

6. 使用SpreadJS提供的导出PDF接口将签署的文件导出

电子签名的实现

初始化Spread工作簿

1、引入以下文件

<link rel="stylesheet" type="text/css" href="node_modules/@grapecity/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
<script src="node_modules/@grapecity/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script>
<script src="new2.ssjson" type="text/javascript"></script>

2、创建用于承载SpreadJS的DOM

<div id="ss" class="sample-spreadsheets" style="height: 900px;">

3、用JS获取DOM对象并进行初始化

var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"));

4、导入合同模板

spread.fromJSON(str);

到这里,我们Spread工作簿已经初始化完成了。当然,你也可以添加对应的CSS调整表单的大小。

关于模板的制作,你可以在在线表格编辑器中根据需求进行绘制,并导出为ssjson文件并通过fromJSON导入到我们的表单中。

接下来,用Canvas画布来实现手写签名区域。

手写签名区域

1、首先,我们先创建签名区域的DOM元素,并定义一个Canvas画布,默认情况下不显示。

<div class="containter" id="box" style="display: none;">
<div class="canvasDiv">
<div id="editing_area">
<canvas id="canvasEdit"></canvas>
</div>
</div>
<div class="btnDiv">
<a id="sign_clear" class="clearBtn">清空</a>
<a id="sign_clear2" class="clearBtn">签署</a>
</div>
</div>

2、引用esign.js和jQuery。Esign.js是一种用鼠标在canvas上绘制的画法。

<script type="text/javascript" src="js/esign.js"></script>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>

3、初始化

$(document).esign("canvasEdit", "sign_show", "sign_clear", "sign_ok");
$(document).on('click', '#sign_clear2', takeScreenshot);

Canvas画布中利用自定义单元格,理论上也是能开发出能够直接签名的单元格。

用户可以直接在单元格进行签名,有兴趣的小伙伴可以尝试用自定义单元格实现。

自定义超链接命令

1、创建超链接

sheet.setValue(32, 10, "审核人签名:")
sheet.setHyperlink(32, 10, { command: "popup" });

2、为超链接设置命令,点击弹出画布

spread.commandManager().register("popup",{
        canUndo: true,
        execute: function (context, options, isUndo) {
        var Commands = GC.Spread.Sheets.Commands;
        // 在此加cmd
        options.cmd = "popup";
        if (isUndo) {
               Commands.undoTransaction(context, options);
                      return true;
               } else {
                      Commands.startTransaction(context, options);
                     document.getElementById("box").style.display = "block";
                      Commands.endTransaction(context, options);
                            return true;
                      }
               }
    });

指定DOM转为图片并设置为单元格背景

1、利用canvas的接口,将画布转为base64,调用接口设置背景

function convertCanvasToImage(canvas) {
return canvas.toDataURL("image/png");
};

function takeScreenshot() {
var canvas = document.getElementById("canvasEdit");
var imgUrl = convertCanvasToImage(canvas); //截取图片路径,该路径为服务器参数
var sheet = spread.getSheet(0);
sheet.getCell(32,13).backgroundImage(imgUrl);
sheet.getCell(35,13).backgroundImage(imgUrl);
sheet.getCell(38,13).backgroundImage(imgUrl);
}

2、关闭签名画布

function tishi(){
document.getElementById("box").style.display = "none";
}
setTimeout(tishi,100)

将电子签名导出PDF

上面已经实现了电子签名内容,但是我们都知道合同需要有打印输出功能,接下来我们继续介绍如何使用pdf打印输出电子签名。

1、引用PDF拓展文件以及filesaver

<script src="node_modules/@grapecity/spread-sheets-pdf/dist/gc.spread.sheets.pdf.min.js" type="text/javascript"></script>
<script src="node_modules/file-saver/dist/FileSaver.min.js" type="text/javascript"></script>

2、调用接口导出PDF

spread.savePDF(function (blob) {
var fileName = 'download';
saveAs(blob, fileName + '.pdf');
}, function (error) {
console.log(error);
}, {
title: 'Test Title',
});

注意:导出中文字符需要注册对应的字体。

总结

以上,我们实现了基于Canvas电子表格实现电子签名并使用PDF导出打印的完整功能,由于Canvas完全取代了页面的dom结构,因此打印时不需要遍历要打印的dom节点的子节点,也不必将每一页所能打印的dom节点高度累加,这样做可以不用再计算dom节点的高度,大幅节省了系统性能,同时实现了较细的页面颗粒度,不会造成大块空白的情况,完全模拟出了word生成pdf的那种效果。同时,也解决了我们在文章开头中提到缘留白、图片跨越、页面滚动后截图不全三个问题。

关注我们的账号,接下来还会为大家带来更多在工作项目中遇到的有趣内容。

来都来了,点个赞再走吧吧~

单元素初识

我们在浏览网页时会经常遇到注册会员的界面,大概像这个样子:

或填写问卷的情况,大概像这个样子:

我们把这些内容称之为表单。

如何向自己的页面中添加表单呢?

添加表单的操作和添加表格类似。

首先我们要在页面中写入<form></form>标签,这是向浏览器声明这里是个表单,它本身并不会显示在页面中,但是可以全局控制表单元素的一些属性,就像表格中的<table></table>标签。

然后再在<form></form>中写入<input/>标签,这个标签的内容就会显示在页面中了,就像表格元素中的<tr><td>标签。不同的是<input/>没有结尾标签。

下面让我们写一写。

首先复制"第一个页面.html"文件。改名为"表单.html",然后清空<body></body>中的内容,将<head></head>中间的<title></title>中间的内容改为"表单",这样方便我们查看测试页面。

示例代码如下:

<!DOCTYPE HTML>
  <html>
  <head> 
  <title>表单 </title>
  </head> 
  <body>
  </body>
  </html>

下面我们要写入表单内容,示例代码如下:

<form> <input/></form>

页面效果如下:

只有一个输入框。下面,我们为输入框添加名称"会员名称:",示例代码如下:

<form> 会员名称: <input/></form>

效果如下:

这样我们就写出了一个简单的表单,如果为表单添加更多内容和设置,就要继续了解表单的属性。

表单元素属性1

<input/>标签通过改变type属性可以变换出不同功能,在页面制作中,我认为<input/>标签中的type属性最重要。

下面我们来看一下type属性不同的值。

图片来源W3School

输入文字:首先,先来看text值。说明很明确,这个属性值的<input>标签主要是用来输入文本,比如"会员名称。"

示例代码如下:

<form> 会员名称: <input type="text"/></form>

页面效果如图所示:我胡乱输入了几个字母

如果不指定type的text值的话,表面看起来并不影响输入内容,但是表单的内容最终是要提交到服务器的,如果不注明type="text",服务器就不能判断你输入的字符到底是一段代码还是一段字符串组成的文本,因此,我们为了让提的交数据在服务器端能被准确识别,一定要写好type的属性。

除此之外变换type值也能为<input/>变换不同功能。

制作提交按钮:例如"submit"(提交)。在我们输入完表单内容后,一般都有一个提交按钮,这个提交按钮也是由<input/>标签来完成的。

示例代码如下:

<form> 会员名称: <input type="text"/> <input type="submit"/></form>

如图所示:

因为<input/>是内联元素,所以"submit"按钮会和之前的<input>显示在一行,换行的话很简单,可以使用<br>标签。

大家观察一下发现,我们并没有给"submit"按钮指定文字,在按钮上却出现了"提交查询"的字样,这是html默认的,如果我们要改变按钮文字就要使用value这个属性。示例代码如下:

<input type="submit" value = "提交"/>

页面效果如下:

其实我们在输入文字时,输入框里会经常有提示文字,当我们点击输入框时,提示文字消失了,这个功能怎么实现?

这又涉及到一个新属性,叫做"placeholder"(提示文字)。

示例代码如下:

<input type="text" placeholder = "请输入英文或汉语拼音"/>

页面效果如下:

下面我们来练习一下,示例代码如下:

<form>
  会员名称:
<input type = "text" placeholder = "请输入英文或汉语拼音"/><br>
  会员密码:<input type = "text" placeholder = "请输入英文字母、特殊符号、数字"/><br>
  确认密码:<input type = "text" /><br><input type = "submit" value = "提交"/><br>
</form>

页面效果如下:(想把密码字符显示为小圆点的读者可以先去属性值列表中找找"password"看看,咱们后面会细致讲解)

制作多选表单:多选表单的type属性值是"checkbox"。

我猜大家也猜到该怎么写了,示例代码如下:

<form>
  兴趣爱好:<br>
  <input type = "checkbox" name="hobby" value = "reading"/>读书
  <input type = "checkbox" name="hobby" value = "film"/>电影
  <input type = "checkbox" name="hobby" value = "painting"/>绘画
  <input type = "checkbox" name="hobby" value = "music"/>音乐
  <br>
  <input type = "submit" value = "submit"/>
  </form>

页面效果如下:

大家可以点点试试,可以多选了。如图:

这时小伙伴们会发现在这组示例中,出现了name和value两个属性。

先说value,在"submit"中,value的值也就是"提交"二字,是直接显示在按钮上的,而这里的value值却没有显示,显示出来的是我们在<input/>标签后面输入的"读书、电影、绘画、音乐"这样的字样。也就是说这里的value不会显示为选框的名字!

那value属性是干嘛的呢?实际上"checkbox"属性下的value属性值是写给后台的服务器看的。

我们向服务器提交选择后,服务器把name的名称作为数据的大类名称,把value值作为大类中的子类名称来存储或分析数据。

比如这个选择表单是有关兴趣爱好的,因此数据的大类属于"爱好"(hobby),即name="hobby",hobby中又分为"reading"(读书),"film"(电影),"painting"(绘画),"music"(音乐),即value="reading"、value="film"等等。这样不同用户的不同选择就按照这个数据组织方式提交给了服务器。

大家明白了吗?

另外需要说明的是,name和value最好使用英文或拼音来书写!

虽然我们目前不涉及后端服务器上的操作,但是在学习时要养成规范书写的习惯。

其实,除了type="submit"的情况外,其他需要输入信息的type属性类型都是要写name属性的,不过不同type属性类型的value却不太一样

下面我们来看看type="text"时的标准写法:当type="text"的时候,不必写value属性,因为value值为用户输入的内容

<form>
  会员名称:
  <input type = "text" placeholder = "请输入英文或汉语拼音" name="memberName"/><br>
  会员密码:
  <input type = "text" placeholder = "请输入英文字母、特殊符号、数字" name="passWord"/><br>
  确认密码:<input type = "text" name="confirmPassWord"/><br>
  <input type = "submit" value = "提交"/><br>
</form>

今天的内容先到这里,我们明天继续讲解"表单元素"。

喜欢的小伙伴请关注和转发,阅读中遇到任何问题请给我留言,如有疏漏或错误欢迎大家斧正,不胜感激!

HTML完整学习目录

HTML序章(学习目的、对象、基本概念)——零基础自学网页制作

HTML是什么?——零基础自学网页制作

第一个HTML页面如何写?——零基础自学网页制作

HTML页面中head标签有啥用?——零基础自学网页制作

初识meta标签与SEO——零基础自学网页制作

HTML中的元素使用方法1——零基础自学网页制作

HTML中的元素使用方法2——零基础自学网页制作

HTML元素中的属性1——零基础自学网页制作

HTML元素中的属性2(路径详解)——零基础自学网页制作

使用HTML添加表格1(基本元素)——零基础自学网页制作

使用HTML添加表格2(表格头部与脚部)——零基础自学网页制作

使用HTML添加表格3(间距与颜色)——零基础自学网页制作

使用HTML添加表格4(行颜色与表格嵌套)——零基础自学网页制作

16进制颜色表示与RGB色彩模型——零基础自学网页制作

HTML中的块级元素与内联元素——零基础自学网页制作

初识HTML中的<div>块元素——零基础自学网页制作

在HTML页面中嵌入其他页面的方法——零基础自学网页制作

封闭在家学网页制作!为页面嵌入PDF文件——零基础自学网页制作

HTML表单元素初识1——零基础自学网页制作

HTML表单元素初识2——零基础自学网页制作

HTML表单3(下拉列表、多行文字输入)——零基础自学网页制作

HTML表单4(form的action、method属性)——零基础自学网页制作

HTML列表制作讲解——零基础自学网页制作

为HTML页面添加视频、音频的方法——零基础自学网页制作

音视频格式转换神器与html视频元素加字幕——零基础自学网页制作

HTML中使用<a>标签实现文本内链接——零基础自学网页制作