整合营销服务商

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

免费咨询热线:

仅需 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%为中国明星项目?创业老兵这样说……



在前面

今年国庆假期终于可以憋在家里了不用出门了,不用出去看后脑了,真的是一种享受。这么好的光阴怎么浪费,睡觉、吃饭、打豆豆这怎么可能(耍多了也烦),完全不符合我们程序员的作风,赶紧起来把文章写完。

这篇文章比较基础,在国庆期间的业余时间写的,这几天又完善了下,力求把更多的前端所涉及到的关于文件上传的各种场景和应用都涵盖了,若有疏漏和问题还请留言斧正和补充。

自测读不读

以下是本文所涉及到的知识点,break or continue ?

  • 文件上传原理
  • 最原始的文件上传
  • 使用 koa2 作为服务端写一个文件上传接口
  • 单文件上传和上传进度
  • 多文件上传和上传进度
  • 拖拽上传
  • 剪贴板上传
  • 大文件上传之分片上传
  • 大文件上传之断点续传
  • node 端文件上传

原理概述

原理很简单,就是根据 http 协议的规范和定义,完成请求消息体的封装和消息体的解析,然后将二进制内容保存到文件。

我们都知道如果要上传一个文件,需要把 form 标签的enctype设置为multipart/form-data,同时method必须为post方法。

那么multipart/form-data表示什么呢?

multipart互联网上的混合资源,就是资源由多种元素组成,form-data表示可以使用HTML Forms 和 POST 方法上传文件,具体的定义可以参考RFC 7578。

multipart/form-data 结构

看下 http 请求的消息体



  • 请求头:

Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryDCntfiXcSkPhS4PN 表示本次请求要上传文件,其中boundary表示分隔符,如果要上传多个表单项,就要使用boundary分割,每个表单项由———XXX开始,以———XXX结尾。

  • 消息体- Form Data 部分

每一个表单项又由Content-Type和Content-Disposition组成。

Content-Disposition: form-data 为固定值,表示一个表单元素,name 表示表单元素的 名称,回车换行后面就是name的值,如果是上传文件就是文件的二进制内容。

Content-Type:表示当前的内容的 MIME 类型,是图片还是文本还是二进制数据。

解析

客户端发送请求到服务器后,服务器会收到请求的消息体,然后对消息体进行解析,解析出哪是普通表单哪些是附件。

可能大家马上能想到通过正则或者字符串处理分割出内容,不过这样是行不通的,二进制buffer转化为string,对字符串进行截取后,其索引和字符串是不一致的,所以结果就不会正确,除非上传的就是字符串。

不过一般情况下不需要自行解析,目前已经有很成熟的三方库可以使用。

至于如何解析,这个也会占用很大篇幅,后面的文章在详细说。

最原始的文件上传

使用 form 表单上传文件

在 ie时代,如果实现一个无刷新的文件上传那可是费老劲了,大部分都是用 iframe 来实现局部刷新或者使用 flash 插件来搞定,在那个时代 ie 就是最好用的浏览器(别无选择)。

DEMO



这种方式上传文件,不需要 js ,而且没有兼容问题,所有浏览器都支持,就是体验很差,导致页面刷新,页面其他数据丢失。

HTML

 <form method="post" action="http://localhost:8100" enctype="multipart/form-data">

        选择文件:
            <input type="file" name="f1"/> input 必须设置 name 属性,否则数据无法发送<br/>
<br/>
            标题:<input type="text" name="title"/><br/><br/><br/>

        <button type="submit" id="btn-0">上 传</button>

</form>

复制代码

文件上传接口

服务端文件的保存基于现有的库koa-body结合 koa2实现服务端文件的保存和数据的返回。

在项目开发中,文件上传本身和业务无关,代码基本上都可通用。

在这里我们使用koa-body库来实现解析和文件的保存。

koa-body 会自动保存文件到系统临时目录下,也可以指定保存的文件路径。



然后在后续中间件内得到已保存的文件的信息,再做二次处理。

  • ctx.request.files.f1 得到文件信息,f1为input file 标签的 name
  • 获得文件的扩展名,重命名文件

NODE

/**
 * 服务入口
 */
var http = require('http');
var koaStatic = require('koa-static');
var path = require('path');
var koaBody = require('koa-body');//文件保存库
var fs = require('fs');
var Koa = require('koa2');

var app = new Koa();
var port = process.env.PORT || '8100';

var uploadHost= `http://localhost:${port}/uploads/`;

app.use(koaBody({
    formidable: {
        //设置文件的默认保存目录,不设置则保存在系统临时目录下  os
        uploadDir: path.resolve(__dirname, '../static/uploads')
    },
    multipart: true // 开启文件上传,默认是关闭
}));

//开启静态文件访问
app.use(koaStatic(
    path.resolve(__dirname, '../static') 
));

//文件二次处理,修改名称
app.use((ctx) => {
    var file = ctx.request.files.f1;//得道文件对象
    var path = file.path;
    var fname = file.name;//原文件名称
    var nextPath = path+fname;
    if(file.size>0 && path){
        //得到扩展名
        var extArr = fname.split('.');
        var ext = extArr[extArr.length-1];
        var nextPath = path+'.'+ext;
        //重命名文件
        fs.renameSync(path, nextPath);
    }
    //以 json 形式输出上传文件地址
    ctx.body = `{
        "fileUrl":"${uploadHost}${nextPath.slice(nextPath.lastIndexOf('/')+1)}"
    }`;
});

/**
 * http server
 */
var server = http.createServer(app.callback());
server.listen(port);
console.log('demo1 server start ......   ');
复制代码

CODE

https://github.com/Bigerfe/fe-learn-code/

TML实现文件夹的上传和下载,前端如何用HTML5实现分片上传GB级大文件,网页中实现文件上传下载的三种解决方案(推荐),HTML5实现文件批量上传组件,JQUERY 实现文件夹上传(保留目录结构),B/S大文件上传支持断点上传,WebService 大文件上传,断点续传分片,HTML+AJAX实现上传大文件问题,用HTML实现本地文件的上传,HTML5实现大文件上传,HTML5实现大文件分片上传思路,利用HTML5分片上传超大文件思路,

WEBUPLOADER 支持 超大上G,多附件上传,JS 大文件分割/分片上传,

百度WEBUPLOADER上传视频等大文件,WEBUPLOAD组件实现文件上传功能和下载功能,JS大文件切片上传,断点续传实现DEMO,前端上传大文件的解决方案,前端上传大文件处理(切片、断点续传),前端大文件上传优化方案——分片上传,vue大文件上传解决方案,vue大文件上传解决方案10G,vue大文件上传解决方案50G,vue大文件上传解决方案100G,html5如何实现大文件断点续传、秒传,

java如何实现大文件断点续传、秒传,SpringBoot如何实现大文件断点续传、秒传,SpringMVC如何实现大文件断点续传、秒传,SpringCloud如何实现大文件断点续传、秒传,

webuploader如何实现大文件断点续传、秒传,百度webuploader如何实现大文件断点续传、秒传,html5实现大文件断点续传、秒传,vue如何实现大文件断点续传、秒传,前端如何实现大文件断点续传、秒传,JavaScript如何实现大文件断点续传、秒传,

html5大文件断点续传、秒传解决方案,html5大文件断点续传、加密上传解决方案,html5大文件断点续传、加密存储解决方案,html5大文件断点续传分片解决方案,html5大文件断点续传分块解决方案,html5大文件断点续传分割解决方案,html5大文件断点续传切割解决方案,

后端我们公司项目组选的是JAVA,因为公司有自己的产品,所以直接使用就行了,针对客户需求这块是进行扩展。

客户这边实际上要传的文件单个大小就有50G左右,所以需要支持断点续传和分片上传,并且要支持多线程上传,能够充分利用带宽资源。

之前在网上找过相关的资料,论坛里面也有网友交流过,还加过很多QQ群和微信群,但是结果都不太令人满意。

技术选型的话用的是jquery,也是一个企业内网系统,用的是之前公司的框架,只是进行功能扩展

分片网上讨论的很多,基本上全部都是用的HTML5的API,这个方案也不是不能用,但是在IE下面就不行了,兼容性差了点,并且也不能进行扩展,不能进行二次开发,限制性非常大,我们技术同事提的要求是需要提供产品完整源代码,

网上的文章全部都没有提供文件夹上传和续传的代码,也没有提供数据库操作的代码,

另外这块我们是要求必须提供产品完整源代码,因为后面我们需要自已来维护,同时是要求能够自主可控的

研发部门的同事调研过百度的webuploader这个组件,发现他实际上就是对Flash和HTML5进行了一个封装,本质还是调的HTML5的API,之前在项目中也用过,尝试过,但是最终都不太满意,一个是兼容性非常差,说的是兼容IE,但是在IE用的是Flash,在很多用户的电脑上用不了,卡顿崩溃发生的太频繁,文件上传的数量一多比如几千个,前端页面就开始卡了,用户体验非常差。这些问题研发部的同事都向百度反应过,但是百度webuploader那边一直没人回,基本上没人管,领导说要求付费提供技术支持,那边也是没人回,联系不上他们任何人。

webuploader这边连个开发人员都联系不到,这个是怎么回事?

用户上传的文件比较大,有20G左右,直接用HTML传的话容易失败,服务器也容易出错,需要分片,分块,分割上传。也就是将一个大的文件分成若干个小文件块来上传,另外就是需要实现秒传功能和防重复功能,秒传就是用户如果上传过这个文件,那么直接在数据库中查找记录就行了,不用再上传一次,节省时间,实现的思路是对文件做MD5计算,将MD5值保存到数据库,算法可以用MD5,或者CRC,或者SHA1,这个随便哪个算法都行。

切片的话还有一点就是在服务器上合并,一个文件的所有分片数据上传完后需要在服务器端进行合并操作。

视频教程:https://www.ixigua.com/7227314770696012322

导入项目:
导入到Eclipse:http://www.ncmem.com/doc/view.aspx?id=9da9c7c2b91b40b7b09768eeb282e647
导入到IDEA:http://www.ncmem.com/doc/view.aspx?id=9fee385dfc0742448b56679420f22162
springboot统一配置:http://www.ncmem.com/doc/view.aspx?id=7768eec9284b48e3abe08f032f554ea2

下载示例:

https://gitee.com/xproer/up6-jsp-eclipse/tree/6.5.40/

工程

NOSQL

NOSQL示例不需要任何配置,可以直接访问测试

创建数据表

选择对应的数据表脚本,这里以SQL为例

修改数据库连接信息

访问页面进行测试

文件存储路径

up6/upload/年/月/日/guid/filename

相关问题:
1.javax.servlet.http.HttpServlet错误
2.项目无法发布到tomcat
3.md5计算完毕后卡住
4.服务器找不到config.json文件

相关参考:

文件保存位置

源码工程文档:https://drive.weixin.qq.com/s?k=ACoAYgezAAw1dWofra

源码报价单:https://drive.weixin.qq.com/s?k=ACoAYgezAAwoiul8gl

OEM版报价单:https://drive.weixin.qq.com/s?k=ACoAYgezAAwuzp4W0a

产品源代码:https://drive.weixin.qq.com/s?k=ACoAYgezAAwbdKCskc
授权生成器:https://drive.weixin.qq.com/s?k=ACoAYgezAAwTIcFph1