整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          僅需 5 步,用 JavaScript 直接通過前端

          僅需 5 步,用 JavaScript 直接通過前端發(fā)送電子郵件

          者 | Mateusz Iwaniuk

          譯者 | 明明如月,責編 | 夕顏

          出品 | CSDN(ID:CSDNnews)

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

          現(xiàn)在,即使是創(chuàng)建最基本的網(wǎng)站,程序員也必須使用現(xiàn)代的功能和技術。甚至像為你的朋友創(chuàng)建簡單的投資組合這樣的基本項目也可能涉及到一些問題,比如從聯(lián)系人表單接收數(shù)據(jù)。有很多方法可以讀取這些數(shù)據(jù)。你可以將表單與數(shù)據(jù)庫連接起來,然后從數(shù)據(jù)庫中讀取傳入的消息來實現(xiàn)功能,但這樣做會給不懂技術的客戶造成困難。

          你為什么不通過發(fā)送電子郵件傳輸信息?

          不使用數(shù)據(jù)庫就能接收到傳入的消息,絕對是最佳選擇,也是最方便用戶的選擇。但問題來了—如何實現(xiàn)呢?你可能認為需要使用某種后端語言。

          實際上,你不必使用任何如 php 或 python 這種后端語言,你甚至不需要用到 node.js!你需要的就是一個簡單的EmailJS 庫。

          本文將介紹下面兩個重要功能:

          • 配置 emailjs 帳戶

          • 使用 JS 發(fā)送電子郵件

          請注意,在我的項目中,我使用了 gulp 和 webpack,我在 src 文件夾存放源碼,dist 存放最終發(fā)布版本的代碼。

          我將分 5 個步驟向你展示如何從頭開始構建電子郵件發(fā)送器。

          步驟1-用 HTML 創(chuàng)建表單

          首先需要創(chuàng)建一個 HTML 表單。你不必放置像 required 或 max 這種驗證屬性,因為稍后,preventDefault 函數(shù)將在你的提交事件上運行,它會讓這些屬性的處理失效。

          表單中最重要的是為每個輸入放置 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 用戶

          要配置你的電子郵件,你必須注冊電子郵件服務。別擔心—使用這個網(wǎng)站非常方便和省時。

          登入后,系統(tǒng)會詢問你的電子郵件服務,它位于個人電子郵件服務區(qū)(personal email service)。在我的例子中,我選擇了 gmail。

          然后,你需要連接你的 gmail 帳戶。這將用來發(fā)送電子郵件給你客戶。例如,如果你關聯(lián)了 xyz@gmail.com 賬戶,你后續(xù)發(fā)送的郵件都將從這個郵箱發(fā)出。所以不要擔心“ Send email on your behalf” 這個授權信息—這正是你需要的!

          連接完 gmail 賬戶后,點擊添加服務(add service)按鈕。

          步驟3-創(chuàng)建郵件模板

          如果你已經(jīng)成功連接了你的 gmail 賬戶,你現(xiàn)在應該在信息中心中。現(xiàn)在需要創(chuàng)建電子郵件模板了。

          切換到電子郵件模板卡,并單擊創(chuàng)建一個新的模板(create a new template)。界面非常友好,所以創(chuàng)建模板不會有任何問題。

          你可以選擇模板的名稱和 ID。我稱之為“我的神奇模板(my_amazing_template)”。

          接下來,你必須指定郵件的內容。

          模板的變量值來自 input 中的 `name` 屬性。你已將變量插入`{{{}}}`符號中。

          不要忘記在“收件人”部分 (右側) 添加電子郵件地址。你的電子郵件將被發(fā)送到該電子郵件地址上。截圖中的收件人郵箱是我自己的公司郵箱。

          這是我的簡單模板,它使用來自 HTML 表單里的 3 個變量。我還指定了接收電子郵件的主題。

          步驟4-保存 API 密鑰

          這部分沒什么特別的。Emailjs 共享授權 API 密鑰,將在發(fā)送電子郵件時使用。當然,放這些鑰匙最好的地方是`.env` 配置。但是因為我使用的是簡單的靜態(tài)文件,我不想使用服務器配置,所以我將它們保存在 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'}

          如果需要將源碼發(fā)布到 GITHUB,不要忘記將 APIKEYS 文件添加到 .GITIGNORE文件中

          步驟5-發(fā)送電子郵件

          現(xiàn)在是該項目最后也是最重要的部分的了。現(xiàn)在我們必須使用 javascript 發(fā)送電子郵件。

          首先,你必須下載 emailjs 包。

          npm i emails-com

          然后,轉到 js 文件,導入庫和 apikeys。

          src/js/main.js

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

          現(xiàn)在是編寫發(fā)送電子郵件功能的時候了

          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 函數(shù)有4個參數(shù):

          你的電子郵件的 ID,在這里:

          TEMPLATE_ID 來自 apikey 文件,

          事件對象來自你的表單提交

          USER_ID 來自 apikey 文件,

          最后,查找表單并添加提交事件監(jiān)聽器:

          src/js/main.js

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

          正如我前面提到的,由于 `preventDefault` 函數(shù),屬性驗證將無法工作。你必須使用 JS 自己進行驗證和清除輸入。

          以上就是全部內容,接下來讓我們測試一下。

          填寫頁面上的表單并發(fā)送。

          我收到電子郵件,內容正是根據(jù)我們的模板和表單數(shù)據(jù)渲染出來的。

          通過上圖可以看出,所有的變量的值都填充到了正確的位置上。

          總結

          通過本文的介紹你會發(fā)現(xiàn)用 JS 發(fā)送郵件并非難事。

          使用 emailjs,你可以簡單的方式發(fā)送電子郵件。

          我相信你未來的用戶會很高興收到來自他們網(wǎng)頁上表單填寫數(shù)據(jù)的t郵件,相信本文對你有幫助。

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

          原文鏈接:

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

          本文為CSDN翻譯文章,轉載請注明出處。

          ?我們想研發(fā)一個機器學習框架,6 個月后失敗了

          ?生產(chǎn)型機器學習已經(jīng)沒那么困難了?

          ?視頻 | 你不知道的"開源"60年秘史

          ?GitHub標星10,000+,Apache項目ShardingSphere的開源之路

          ?阿里技術專家告訴你,如何畫出優(yōu)秀的架構圖?

          ?加拿大API平臺如何做到30%為中國明星項目?創(chuàng)業(yè)老兵這樣說……

          一篇文章我給大家說明了如何從零開始搭建一個node的服務端框架,我們用到了Egg框架。Egg框架我不再過多介紹,如果有小伙伴想了解,可以回去看我以前寫的文章,會有相關的介紹。這次我將在上次搭建的框架上進行延伸,講一下如果用Egg框架連接數(shù)據(jù)庫,并且實現(xiàn)對數(shù)據(jù)的增刪查改。接下來我們直接進入主題。

          安裝數(shù)據(jù)庫插件

          我本次選用的數(shù)據(jù)庫是MySQL。所以我們安裝Egg官方的數(shù)據(jù)庫插件即可,首先我們安裝插件 egg-mysql我們在項目根目錄打開命令提示符,輸入命令行:npm i --save egg-mysql 。回車等待插件下載安裝完成。

          npm i --save egg-mysql

          配置插件

          命令行下載安裝插件完成后,我們下一步的工作就是在項目中開啟并配置egg-mysql插件。具體操作如下:

          首先我們要在項目中開啟數(shù)據(jù)庫。找到項目中的/config/plugin.js文件我們需要在里面添加幾行代碼,如下所示。

          //開啟數(shù)據(jù)庫插件
            mysql : {
              enable: true,
              package: 'egg-mysql',
            }

          然后我們還要在 config/config.default.js 中配置各個環(huán)境的數(shù)據(jù)庫連接信息。具體配置如下。

          //添加數(shù)據(jù)庫連接信息
            config.mysql={
              // 單數(shù)據(jù)庫信息配置
              client: {
                // host
                host: 'localhost',
                // 端口號
                port: '3306',
                // 用戶名
                user: 'root',
                // 密碼
                password: '123456',
                // 數(shù)據(jù)庫名
                database: 'testdb',
              },
              // 是否加載到 app 上,默認開啟
              app: true,
              // 是否加載到 agent 上,默認關閉
              agent: false,
            };

          到此步驟我們的數(shù)據(jù)庫插件已經(jīng)安裝完成并且配置好了。那我們怎么實現(xiàn)數(shù)據(jù)的增刪查改呢?大家請繼續(xù)往下看。

          數(shù)據(jù)操作-新增用戶

          首先我們看一下怎么新增數(shù)據(jù)。我們在mysql的testdb實例中新建一個user空表。如下圖所示。

          我們的egg框架也遵循MVC的架構所以我們一般會在service層里面寫我們邏輯處理的代碼,而controller層則是獲取前端數(shù)據(jù),回傳數(shù)據(jù)的控制層。所以我們操作數(shù)據(jù)庫的代碼是寫在service文件夾里面的。

          我們在app/service文件夾里面新建一個user.js文件。在里面寫個新增用戶的方法,該方法就是把數(shù)據(jù)存到數(shù)據(jù)庫中。具體代碼如下。

          const Service=require('egg').Service;
          
          class UserService extends Service {
          
            //新增用戶data是有controller層傳遞過來的數(shù)據(jù)記錄。
            async addUser(data) {
          
              const {ctx, app}=this;
              let result={};
              try {
                data.id=0;//定義id=0,因為數(shù)據(jù)庫已經(jīng)設置id為主鍵,并且自增。所以只需要賦值0即可。
                // 在 user 表中,插入前端提交上來的數(shù)據(jù)記錄
                const info=await app.mysql.insert('user', data); 
            
                //插入成功后。
                if(info.affectedRows===1){
                  //給前端返回一個Json的對象
                  result={
                    state: 0, //自定義的狀態(tài)碼
                    msg: "添加成功", //返回的消息
                    data: info.insertId, //新增的記錄的id
                  }
                }
          
              } catch (err) {
                //插入數(shù)據(jù)失敗的返回結果
                result={
                  state: 1, 
                  msg: err,
                  data: null,
                }
              }
              
              return result
            }
          };
          module.exports=UserService;

          然后我們在app/controller文件夾里新建一個user.js文件。在這里我們需要獲取前端提交上來的數(shù)據(jù),并且將數(shù)據(jù)處理的結果返回給前端。具體代碼如下。

          'use strict';
          
          const Controller=require('egg').Controller;
          /**
           * @Controller 用戶管理
           */
          class UserController extends Controller {
          
            /**
            * @summary 新增用戶
            * @router post /user/add
            * @request body userAddRequest 
            * @response 200 
            */
            async addUser() {
              const { ctx }=this;
          
              //通過ctx.request.body的方式,可以獲取到前端post方式提交上來的數(shù)據(jù)
              const data=ctx.request.body;
          
              //調用service層的addUser方法。并且返回相應的結果
              const userInfo=await ctx.service.user.addUser(data);
              
              //向前端接口響應數(shù)據(jù)。
              ctx.body=userInfo;
            }
          
          }
          
          module.exports=UserController;

          最后我們定義一個路由,讓前端請求訪問此路由。框架會監(jiān)聽路由是否被訪問,如果被訪問了則會調用我們定義在controller層的新增用戶的方法。我們在app/router.js文件中添加如下代碼,即可完成路由的定義。

          //新增用戶路由
            router.post('/user/add', controller.user.addUser);

          完成這步驟后,我們一個新增用戶的功能就已經(jīng)完成了。接下里我們就測試一下它的實際效果。我們運行命令:npm run dev。啟動項目,然后打開網(wǎng)頁http://127.0.0.1:7001,可以直接在swagger-ui.html頁面中進行測試。結果如下圖所示。

          經(jīng)過測試,數(shù)據(jù)已經(jīng)添加完成。所以數(shù)據(jù)庫連接也是正常的。

          本次分享暫時先告一段落。請各位小伙伴抬起你們發(fā)財?shù)男∈郑c個贊唄。下次我將會進行和大家分享對數(shù)據(jù)查改刪的方法。關注我!!!更多精彩分享不迷路。

          了執(zhí)行Javascript,需要在HTML文件內以特定的方式書寫JavaScript的代碼,JavaScript的書寫方法有多種,其執(zhí)行的流程也各不相同:

          1 <script>標簽嵌入

          此種嵌入方法無法操作<script>之后的DOM元素。因為<script>之后的DOM元素還未構造,因此在<script>標簽內就無法取得位于其后的DOM元素。

          2 讀取外部JavaScript文件

          此種嵌入方法可以指定defer、async屬性。defer可以推遲執(zhí)行,async可以異步執(zhí)行。

          3 onload嵌入

          此種嵌入方法在頁面讀取完后再對其執(zhí)行,所以可以對所有的DOM元素操作。

          <body onload="alert('hello')">
          window.onload=function(){alert('hello');};

          當window.onload事件觸發(fā)時,頁面上所有的DOM、樣式表、腳本、圖片、flash都已經(jīng)加載完成了。

          //window.onload不能同時編寫多個。
          //以下代碼無法正確執(zhí)行,結果只輸出第二個。
          window.onload=function(){
            alert("test1");
          };
          
          window.onload=function(){
            alert("test2");
          };
          
          //$(document).ready()能同時編寫多個
          //結果兩次都輸出
          $(document).ready(function(){ 
             alert("Hello World"); 
          }); 
          $(document).ready(function(){ 
             alert("Hello again"); 
          }); 

          window.onload和body中onload也有些許區(qū)別:

          <html xmlns="http://www.w3.org/1999/xhtml">
          <head>
              <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
              <title></title>
              <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.0.js"></script>
              <script language="javascript">
                  window.onload=haha;
                  function haha(){console.log("window.onload");}
          
                  if(document.addEventListener){
                      function DOMContentLoaded(){
                          console.log("DOMContentLoaded");
                      }
                      document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
                  }</script>
          </head>
          <body onload="console.log('bodyonload');">
                  <div id="div1">a</div>
          </body>
          </html>

          在IE10和FireFox下,結果為 :

          "DOMContentLoaded"
          "bodyonload"

          說明body中的onload會覆蓋window.onload

          在chrome下,結果為:

          DOMContentLoaded
          window.onload
          bodyonload

          然后,如果把javascript代碼移到最下面,結果又會是什么樣呢?

          chrome和IE10、FireFox的結果竟然是一樣的:

          DOMContentLoaded
          window.onload

          IE 10、Fire Fox可以理解,window.on load和body中的 on load 誰在下面就是誰覆蓋誰,只會執(zhí)行后面的那個。

          4 DOM ContentLoaded嵌入

          onload方法可能需要等待時間,而本方法可以在完成HTML解析后發(fā)生的事件,減少等待時間。

          在chrome、IE10和FireFox中,執(zhí)行結果是:DOMContentLoaded然后才是onload的輸出。所以說一般情況下,DOMContentLoaded事件要在window.onload之前執(zhí)行,當DOM樹構建完成的時候就會執(zhí)行DOMContentLoaded事件。

          <html xmlns="http://www.w3.org/1999/xhtml">
          <head>
              <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
              <title></title>
              <script type="text/javascript" src="jquery2.js"></script>
              <script language="javascript">
                  window.onload=haha;
                  function haha(){console.log(document.getElementById("div1"));}
                  if(document.addEventListener){
                      function DOMContentLoaded(){
                          console.log("DOMContentLoaded");
                      }
                      document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
                  }
              </script>
          </head>
          <body>
              <div id="div1">a</div>
          </body>
          </html>

          如果你是個jQuery使用者,你可能會經(jīng)常使用$(document).ready();或者$(function(){}),這都是使用了DOMContentLoaded事件

          5 動態(tài)載入JavaScript文件

          5.1 使用原生js方法

          動態(tài)創(chuàng)建script標簽,并指定script的src屬性

          function loadJs(url, callback) {
              var script=document.createElement('script');
              script.type="text/javascript";
              if (typeof(callback) !="undefined") {
                  if (script.readyState) {
                      script.onreadystatechange=function() {
                          if (script.readyState=="loaded" || script.readyState=="complete") {
                              script.onreadystatechange=null;
                              callback();
                          }
                      }
                  } else {
                      script.onload=function() {
                          callback();
                      }
                  }
              }
              script.src=url;
              document.body.appendChild(script);
          }
          loadJs("test.js", function() {
              alert('done');
          });

          還可以使用同樣的原理動態(tài)加載css文件,只不過插入的的父節(jié)點是head標簽。

          5.2 使用document.write/writeln()方式

          該種方式可以實現(xiàn)js文件的動態(tài)加載,原理就是在重寫文檔流,這種方式會導致整個頁面重繪。

          document.writeln("<script src=\"http://lib.sinaapp.com/js/jquery/1.6/jquery.min.js\"></script>");

          需要注意的是特殊字符的轉義。

          5.3 使用jQuery

          使用getScript(url,callback)方法實現(xiàn)動態(tài)加載js文件

          $.getScript('test.js',function(){
              alert('done');
          });

          -End-


          主站蜘蛛池模板: 激情综合一区二区三区| 无码精品人妻一区二区三区免费看 | 亚洲AV无码国产一区二区三区| 日本片免费观看一区二区| 99精品久久精品一区二区| 日韩精品在线一区二区| 国产精品毛片一区二区三区| 国产亚洲综合一区柠檬导航 | 亚洲A∨无码一区二区三区| 国产在线观看一区二区三区| 成人久久精品一区二区三区| 欧美av色香蕉一区二区蜜桃小说 | 国产精品亚洲综合一区在线观看 | 男插女高潮一区二区| 国产亚洲福利精品一区二区| 波多野结衣AV无码久久一区| 亚洲视频免费一区| 精品3d动漫视频一区在线观看| 中文乱码精品一区二区三区| 中文字幕一区二区三区5566| 国产麻豆剧果冻传媒一区| 亚洲一区二区三区AV无码| 亚洲欧洲无码一区二区三区| 亚洲国产成人精品久久久国产成人一区二区三区综 | 能在线观看的一区二区三区| 九九久久99综合一区二区| 亚洲国产精品一区二区久久hs| 国产激情无码一区二区三区| 福利一区福利二区| 亚洲综合一区国产精品| eeuss鲁片一区二区三区| 一区二区不卡久久精品| 亚洲国产成人一区二区三区 | 国产一区二区三区精品视频| 中文字幕精品无码一区二区 | 精品国产一区在线观看| 成人精品一区二区不卡视频| 国产亚洲综合精品一区二区三区 | 日韩视频一区二区在线观看| 无码精品人妻一区二区三区影院| 国产亚洲一区二区三区在线不卡 |