以前我用nwjs作過一個博客園文章編輯器的客戶端html
發了好幾個版本,最後一個版本到5.0.0了前端
其實第一個版本已經很好了,不滿足,後來本身又作了兼容markdown的,結果用來用去,發現不是本身想要的vue
也一直沒動手作新的,寫博客的頻率也降下去了。node
最近搞了個APP(還沒上線),打算把心得寫到博客裏,發現沒有趁手的編輯器jquery
因而動手從新搞這個東西git
此次用Vue+electron來搞,算是技術的主流了github
先把搞這個東西的心得寫出來,但願你們不吝賜教。web
截幾個圖給你們看看,chrome
列表界面:vue-cli
文章編輯的界面:
博客登陸(引入博客園的登陸畫面,使用官方提供的登陸機制)
文章列表(能夠檢索到你博客園內全部的隨筆文章,支持分頁,支持文章分類)
修改文章(你博客園內全部的歷史隨筆文章,均可以用此工具編輯修改)
新增文章(從無到有撰寫一篇新的隨筆文章,支持保存爲草稿)
截圖工具截圖後直接黏貼到編輯器中(QQ截圖、微信截圖,直接黏貼到編輯器中)
圖片拖拽到編輯器中自動上傳
插入公式、插入地圖、插入表情、插入表格、插入音樂、插入代碼...包羅萬象;
純客戶端,直接與博客園服務端通訊(沒有任何自建服務,不採集用戶任何信息)
新版本升級提醒功能;
開源,開源地址:https://gitee.com/xland/cnblogs
操做系統兼容蘋果和windows,下載地址:https://gitee.com/xland/cnblogs/releases
這個程序用到了electron和vue
連接這兩個東西的橋樑是electron-vue
建議你們給個star,有這麼個工具真的能省不少力氣(有錢的捧個💰場,沒錢的捧個✨場)
用npm工具初始化環境的命令爲:
npm install -g vue-cli vue init simulatedgreg/electron-vue cnblogs51 cd cnblogs51 npm install npm run dev
幾行命令執行完,一個默認的模板畫面就啓動起來了;
咱們簡單介紹一下electron-vue
咱們知道vue有hot-reload的能力,
就是你改了什麼代碼,立刻能在界面上表現出來,很是有利於調試;
electron-vue也有這個能力
爲了作到這一點,他在你的開發機上起了http的服務;
然而你發佈出來的程序,啓動的時候,並無在客戶機上也開一個http的服務;
也就是說,開發機上調試程序,界面訪問的是http://..........
客戶機上,運行程序界面加載的事:file://.........
他src目錄下,有兩個子目錄,一個是main;一個是renderer
之因此這樣分目錄,跟electron的工做原理有關係
electron與nwjs不一樣,
nwjs把nodejs裏的v8和chrome瀏覽器裏的v8整合到一塊兒了,能夠直接在網頁JS裏訪問nodejs的庫
electron並無這麼作,它分兩個主要進程,一個主進程,一個渲染進程;
對應起來就是剛纔說的main目錄和renderer目錄
main目錄放主進程相關的東西
renderer目錄放界面相關的東西
若是你開發過vue的程序,你不會對renderer目錄下的東西陌生,就是一個純粹的vue項目應有的東西
main目錄下,一個index.js,一個index.dev.js
若是你的程序處於調試狀態,那麼這兩個文件都會起做用(經過npm run dev命令啓動的程序);
若是你的程序處於發佈狀態,那麼只有index.js文件起做用(經過npm run build命令編譯打包後被安裝的程序);
若是你看了package.json文件
會發現以下配置:
"main":"./dist/electron/main.js"
這是electron程序啓動的入口,
這裏的main.js就是index.js和index.dev.js合併打包出來的
注:nwjs入口程序是一個.html的文件;electron的入口程序是一個.js的文件
electron經過js入口程序加載畫面
在我們這個工程下,他加載的事src目錄下的index.ejs畫面
這其實也是vue程序的宿主頁面
根目錄下,還有一個build子目錄,
若是沒有,你執行一下npm run build命令就有了,
你產品開發完,打包出來的東西,就放在這個目錄下;
這個目錄下,有一個icons的子目錄
打包的時候,從這個子目錄裏取圖標,
打包出來的可執行文件的圖標,就是從這裏得來的;
還有一個很是重要的目錄是根目錄下的static目錄
前面咱們說了electron-vue開發環境和生產環境的不一樣;
在這個目錄裏放的,就是一些靜態的資源
不管是開發環境,仍是生產環境,
你只須要經過下面這樣的路徑訪問方式,就能加載到相應的資源
src="static/your/path/file.js"
electron程序的入口是一個js文件
在js文件裏打開一個窗口,讓這個窗口加載指定的畫面
functioncreateWindow () { mainWindow = newBrowserWindow({ height:800, useContentSize:true, width:1200}) mainWindow.loadURL(winURL) mainWindow.on('closed', ()=>{mainWindow =null}) } app.on('ready', createWindow);
app在ready的時候,建立了一個窗口,並加載了一個路徑
app和窗口都是經過下面的代碼得來的:
import{ app, BrowserWindow } from 'electron'
路徑是經過下面的代碼得來的:
constwinURL = process.env.NODE_ENV === 'development'? `http://localhost:9080`: `file://${__dirname}/index.html`
electron容許打開子窗口,也容許開多標籤頁
在蘋果端,當全部窗口都關閉後,就要退出程序,代碼以下:
app.on('window-all-closed', ()=>{ if(process.platform !== 'darwin') { app.quit(); } })
其實並非繞不開,而是繞開的成本過高了,不值得。
就像咱們作IT系統,永遠沒有一個系統是絕對安全的,
若是破壞一個系統的成本足夠高,那麼咱們就認爲這個系統是足夠安全的;
咱們想本身寫畫面,在本身的畫面上顯示博客分類、文章列表;
在本身的畫面上新建、編輯、保存文章;
這就涉及到跨域的問題
一開始我考慮,本身寫模擬登陸的代碼,登陸成功以後本身保存會話信息;
後來發現博客園還有這個東西
要想繞開這個東西,成本一會兒高不少
由於這個東西的目的,就是爲了防止被繞開的
(其實我有思路,但並未作嘗試)
後來想到,就算繞開又如何呢?
難道我去把博客園的服務端接口都分析一遍
真的用本身的代碼,訪問博客園的接口嗎?
我爲何不經過一個隱藏的iframe,來控制博客園的界面
經過它獲取我想呈如今本身界面上的數據;
也經過它,提交我本身界面上的用戶數據;
這樣就只要用博客園前端頁面內置的jquery獲取文章數據;
而後再用jquery操做提交、草稿按鈕就能夠了。
在nwjs環境裏,咱們真的就是用的一個iframe,代碼以下:
var iframeTag = 'nwUserAgent="Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.3538.400 QQBrowser/9.6.12501.400"'; var articleDiv = '<iframe id="articleFrame" src="[your url]" nwdisable nwfaketop '+bky.iframeTag+'></iframe>';
這裏涉及到三個特殊的屬性
nwdisable:
是爲了防止這個iframe加載的頁面去調用nwjs的一些功能,好比說格盤,由於畢竟咱們加載的頁面不是咱們本身提供的,要爲咱們用戶的安全着想;
nwfaketop:
若是沒有這個,在iframe頁面裏調用window.top,就能訪問到咱們的頁面的window對象,不少廠商都是經過這個來判斷本身是否是被別人iframe了,有了這個標籤,window.top就訪問不到咱們
nwUserAgent:
咱們經過這個標籤來設置iframe加載頁面時使用的user-agent,進一步隱藏本身,不被服務提供方發現;
在electron裏,不是直接用iframe,而是用了electron內置的一個webview的標籤
<webview ref="frame" :preload="preloadJsPath" :src="enterUrl" :useragent="$root.agent"></webview>
(注意:上面這行代碼用到了vue的一些特性)
它也有useragent屬性,跟nwjs裏的nwUserAgent同樣
它默認就是不容許被加載頁面訪問electron的底層API的,
由於根本就不是iframe,因此window.top也訪問不到它的宿主頁面;
個人目的是讓個人用戶使用我開發的畫面
個人客戶在不須要的時候,不須要看到博客園的任何界面
因此這個webview默認是隱藏的;
在用戶第一次打開應用的時候,這個webview會直接加載博客園後臺的頁面:
enterUrl:"https://i.cnblogs.com/posts"
若是你第一次使用這個應用,你本地確定沒有會話信息,因此你訪問後臺頁面,博客園會給你跳轉到登陸頁面;
咱們能夠在webview的dom-ready事件裏監控webview內部的url變化,代碼以下:
var self = this; var frame = this.$refs.frame; frame.addEventListener("dom-ready",function(e){ if(frame.src.search('https://passport.cnblogs.com/user/signin') == 0) { frame.style.zIndex ="99"; }else{ frame.style.zIndex = "1"; //other code... } });
當url變成登陸頁面時,咱們就讓webview顯示出來,
這時咱們的應用跟一個普通的瀏覽器沒有任何區別,
咱們的客戶也是在與博客園的登陸頁面交互,
當用戶登陸成功以後,url又會變成https://i.cnblogs.com/posts,
此時,我又讓webview隱藏起來,把我本身的界面呈現給用戶
這個時候用戶已經登陸成功了
雖然我本身的界面仍是沒有博客園的會話信息
可是這個webview已經具有了合法的身份
能夠隨意訪問博客園後臺的任意API
接下來,咱們的界面就會以這個webview爲橋樑,與博客園後臺服務進行交互。
想通了這些,我發現我手裏多了一把錘子🔨
有不少事情能夠作呀
寫個自動下單工具、秒殺工具、搶票工具之類的,都是易如反掌;
不會在糾結怎麼模擬登錄,就算真要模擬登錄,也不是徹底沒辦法;
由於在這個環境下,目標網站的前端代碼,徹底暴露在你眼前,隨你想怎麼控制就怎麼控制
具體怎麼搞,咱們一下篇再說
,有着急的朋友,能夠先看我開源出來的代碼
不過,我想要作的就是讓這個工具兼容更多的博客
如今博客園已經作差很少了,接下來兼容什麼呢?CSDN?知乎?簡書?segmentfault?歡迎你們留言;
另外,安裝程序的下載地址爲:https://gitee.com/xland/cnblogs/releases
你們發現什麼問題能夠直接提issue,若是你們期待什麼新功能,也能夠提issue(qq羣:51021155)
喜歡的朋友,請幫忙點個贊,給個星