Node接收電子郵件的實例代碼
上一篇文章寫了如何通過node發(fā)送電子郵件,有發(fā)送就會有接收嘛,所以這篇文章來說說關(guān)于在node中如何接收電子郵件。
郵件協(xié)議
在開始這篇文章之前我們首先了解三個協(xié)議smtp(Simple Mail Transfer Protocol)簡單郵件傳輸協(xié)議,pop3(Post Office Protocol 3)郵局協(xié)議第三版本,imap(Internet Mail Access Protocol)internet消息訪問協(xié)議。
smtp協(xié)議
簡單郵件傳輸協(xié)議:是一種基于文本的電子郵件傳輸協(xié)議,用于從源地址到目的地址傳輸郵件的規(guī)范,通過它來控制郵件的中轉(zhuǎn)方式,是因特網(wǎng)中用于在郵件服務(wù)器之間交換郵件的協(xié)議。SMTP是一個“推”的協(xié)議,它不允許根據(jù)需要從遠(yuǎn)程服務(wù)器上“拉”來消息。要做到這點,郵件客戶端必須使用POP3或IMAP。所以發(fā)送郵件的時候我們需要簡單的了解下面的這兩種協(xié)議。
pop3協(xié)議
POP3協(xié)議允許電子郵件客戶端下載服務(wù)器上的郵件,但是在客戶端的操作(如移動郵件、刪除郵件、標(biāo)記已讀等),不會反饋到服務(wù)器上,比如通過客戶端收取了郵箱中的3封郵件并移動到其他文件夾,郵箱服務(wù)器上的這些郵件是沒有同時被移動的。也就是說POP3協(xié)議實際上是下載了一份郵件的副本到本地郵件客戶端,而且對本地郵件副本的操作只會影響本地數(shù)據(jù)。多個郵件客戶端里面的郵件的狀態(tài)可能會不一致。
imap協(xié)議
IMAP(Internet消息訪問協(xié)議)也是提供面向用戶的郵件收取服務(wù)。常用的版本是IMAP4。與POP3協(xié)議類似允許電子郵件客戶端下載服務(wù)器上的郵件,不同的是,開啟了IMAP后,您在電子郵件客戶端收取的郵件仍然保留在服務(wù)器上,同時在客戶端上的操作都會反饋到服務(wù)器上,如:刪除郵件,標(biāo)記已讀等,服務(wù)器上的郵件也會做相應(yīng)的動作。換句話說,IMAP把遠(yuǎn)程文件夾當(dāng)成本地文件夾來操作,它們之間類似于雙向同步。這樣的好處是,當(dāng)你在多個郵件客戶端看見的郵件的狀態(tài)是一致的。本次接收郵件我們也使用此協(xié)議來實現(xiàn)。
接收郵件測試過程
接收郵件實際上做的是一個郵件客戶端的東西,對于底層的實現(xiàn)在npm上有一個寫好的第三的庫node-imap(node.js的imap客戶端模塊)這個模塊幫助我們封裝了很多的底層操作,但是這個模塊返回的數(shù)據(jù)像附件、消息、郵件頭等都是未解碼的原始數(shù)據(jù),所以還需要對數(shù)據(jù)進(jìn)行解碼,解碼的模塊在npm上也找到了一個寫好的庫Mailparser它是一個node高級電子郵件解析器,能夠解析即使非常大的數(shù)據(jù)(100MB+),而且開銷相對比較低。
使用imap接收郵件的過程可以用下面一張圖表示
imap接收郵件測試過程
本次測試的大概過程如下
- 在pc上登錄qq郵箱
- 通過qq郵箱發(fā)郵件到gamil(不同郵件服務(wù)器之間發(fā)郵件過程比較復(fù)雜,過程略)
- 在pc上通過寫好的基于imap的程序去拉取gmail的郵件,同時本地的修改(標(biāo)記郵件,刪除郵件)會同步到gmail服務(wù)器
安裝node第三方包
npm install --save imap mailparser
郵件接收服務(wù)器我選擇Gmail,發(fā)送郵件的服務(wù)器使用qq郵箱。
使用qq郵箱發(fā)送一封帶有附件的郵件
通過程序接收郵件
查看附件保存時否正確
核心代碼
var Imap = require('imap') var MailParser = require("mailparser").MailParser var fs = require("fs") var imap = new Imap({ user: 'yourname@gmail.com', //你的郵箱賬號 password: 'yourpassword', //你的郵箱密碼 host: 'imap.gmail.com', //郵箱服務(wù)器的主機地址 port: 993, //郵箱服務(wù)器的端口地址 tls: true, //使用安全傳輸協(xié)議 tlsOptions: { rejectUnauthorized: false } //禁用對證書有效性的檢查 }); function openInbox(cb) { imap.openBox('INBOX', true, cb); } imap.once('ready', function() { openInbox(function(err, box) { console.log("打開郵箱") if (err) throw err; imap.search(['UNSEEN', ['SINCE', 'May 20, 2017']], function(err, results) {//搜尋2017-05-20以后未讀的郵件 if (err) throw err; var f = imap.fetch(results, { bodies: '' });//抓取郵件(默認(rèn)情況下郵件服務(wù)器的郵件是未讀狀態(tài)) f.on('message', function(msg, seqno) { var mailparser = new MailParser(); msg.on('body', function(stream, info) { stream.pipe(mailparser);//將為解析的數(shù)據(jù)流pipe到mailparser //郵件頭內(nèi)容 mailparser.on("headers", function(headers) { console.log("郵件頭信息>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); console.log("郵件主題: " + headers.get('subject')); console.log("發(fā)件人: " + headers.get('from').text); console.log("收件人: " + headers.get('to').text); }); //郵件內(nèi)容 mailparser.on("data", function(data) { if (data.type === 'text') {//郵件正文 console.log("郵件內(nèi)容信息>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); console.log("郵件內(nèi)容: " + data.html); } if (data.type === 'attachment') {//附件 console.log("郵件附件信息>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"); console.log("附件名稱:"+data.filename);//打印附件的名稱 data.content.pipe(fs.createWriteStream(data.filename));//保存附件到當(dāng)前目錄下 data.release(); } }); }); msg.once('end', function() { console.log(seqno + '完成'); }); }); f.once('error', function(err) { console.log('抓取出現(xiàn)錯誤: ' + err); }); f.once('end', function() { console.log('所有郵件抓取完成!'); imap.end(); }); }); }); }); imap.once('error', function(err) { console.log(err); }); imap.once('end', function() { console.log('關(guān)閉郵箱'); }); imap.connect();
默認(rèn)情況下抓取郵件后郵件服務(wù)器的郵件狀態(tài)為未讀,如果要在抓取后讓郵箱服務(wù)器中的郵件狀態(tài)變?yōu)橐炎x,可以修改
var f = imap.fetch(results, { bodies: '' });
為
var f = imap.fetch(results, { bodies: '', markSeen: true });
參考文檔
后記
如果google郵箱如果開啟了二次認(rèn)證,那么你需要在google后臺生成一個專用密碼來登錄google郵箱拉取郵件。
通過一個簡單的例子實現(xiàn)了如何使用node和imap協(xié)議來接收郵件,結(jié)合上篇node發(fā)送電子郵件文章的內(nèi)容,一個簡單的郵件客戶端的基本收信發(fā)信功能就有了,但是想實現(xiàn)一個功能完善用戶體驗好的郵件客戶端就需要不斷揣摩它,設(shè)計它,完善它,希望這篇文章能帶給你啟發(fā),可以實現(xiàn)一個屬于你自己的郵件客戶端。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
從零學(xué)習(xí)node.js之簡易的網(wǎng)絡(luò)爬蟲(四)
簡單的爬蟲實現(xiàn)原理很簡單:發(fā)送http請求至目標(biāo)地址獲取HTML頁面數(shù)據(jù),然后從獲取來的頁面數(shù)據(jù)中提取需要的數(shù)據(jù)保存。下面這篇文章主要介紹了利用node.js實現(xiàn)簡易的網(wǎng)絡(luò)爬蟲的相關(guān)資料,需要的朋友可以參考下。2017-02-02詳解nodeJs文件系統(tǒng)(fs)與流(stream)
這篇文章主要介紹了詳解nodeJs文件系統(tǒng)(fs)與流(stream),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01把Node.js程序加入服務(wù)實現(xiàn)隨機啟動
這篇文章主要介紹了把Node.js程序加入服務(wù)實現(xiàn)隨機啟動,本文使用qckwinsvc實現(xiàn)這個需求,講解了qckwinsvc的安裝和使用,需要的朋友可以參考下2015-06-06nodejs實現(xiàn)截取上傳視頻中一幀作為預(yù)覽圖片
這篇文章主要為大家詳細(xì)介紹了nodejs實現(xiàn)截取上傳視頻中一幀作為預(yù)覽圖片,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12