以前原本想不寫這個功能的,結果客戶死活要qq登陸! 實在沒辦法就寫了,順便寫個文章!
在寫以前有兩個問題:
1: 打開qq受權頁面點擊頁面中的連接會又打開一個頁面! .....
2: 受權以後是否成功很難去判斷 web
不過腦海中有一個想法就是,electron就是一個相似於瀏覽器同樣,既然是瀏覽器那確定能夠阻止連接的點擊 也能夠判斷狀態!
就去啃文檔了!!!shell
推薦你們去w3c去看文檔 比較全 並且速度較快 文檔也比較新: https://www.w3cschool.cn/elec...編程
https://electronjs.org/docs 這裏面的響應速度比較慢 裏面不少文檔都好久了 參數也有失效的!!!json
言歸正傳 說qq登陸!segmentfault
後端是使用PHP實現的 沒什麼難度,主要的就是客戶端的一些處理!後端
<template> <div> <button @click="qqLogin">qq登陸</button> </div> </template> <script> export default { name: "home", mounted() { this.$electron.ipcRenderer.on('reply', (e, data) => { console.log(data) let httpCode = data.request_code[0]; if (httpCode === '1') { alert(data.token[0]) } }) }, methods: { qqLogin() { //請求服務器獲取受權頁面和參數 this.$http.get('xxxxx') .then((result) => { if (result.data.status === 1) { this.$electron.ipcRenderer.send('qqLogin', {url: result.data.data}); } }) .catch() }, } } </script>
解決打開qq受權頁面點擊頁面中的連接會又打開一個窗口的問題 使用webContents 的 new-window 事件 組織默認事件 調用Shell利用默認瀏覽器打開就好了!api
loginWindow.webContents.on('new-window', (event, url) => { event.preventDefault(); shell.openExternal(url); });
到這個問題後我就想到一個詞 那就是 Response 和 code 而後就去搜索了嘛 結果在 webContents找到了! did-get-redirect-request
事件 !
可是咱們不能直接使用他 要在點擊受權以後再去使用他數組
loginWindow.webContents.on('will-navigate', (e, url,) => { content.on('did-get-response-details', (e, status, url, originalURL, httpResponseCode, requestMethod, referrer, header) => { if (httpResponseCode === 200) { event.sender.send('reply', header); // loginWindow.close(); } }) });
will-navigate事件解釋:
當用戶或 page 想要開始導航的時候發出事件.它可在當 window.location 對象改變或用戶點擊 page 中的連接的時候發生.
當使用 api(如 webContents.loadURL 和 webContents.back) 以編程方式來啓動導航的時候,這個事件將不會發出.
它也不會在頁內跳轉發生, 例如點擊錨連接或更新 window.location.hash.使用 did-navigate-in-page 事件能夠達到目的瀏覽器
did-get-response-details 事件解釋:
當有關請求資源的詳細信息可用的時候發出事件. status 標識了 socket連接來下載資源.服務器
拿到這兩個以後咱們就能夠寫代碼啦!
在點擊受權以後受權頁面會跳轉到咱們服務器的一個回調地址 在裏面作一個操做 好比獲取用戶token
亂七八糟的! 以後將生成的token
返回給客戶端!
可是要注意這裏服務端返回的數據客戶端不能解析 你們可使用:findInPage
去查詢返回的內容!
可是我沒去這麼作
由於 did-get-response-details
事件返回了:status
,newURL
,originalURL
,httpResponseCode
,requestMethod
,referrer
,headers
八個參數
最後咱們只須要判斷httpResponseCode
是200的時候 將header
裏面的參數從主進程返回給渲染進程
大概的數據是這樣的:
access-control-allow-credentials:["true"] access-control-allow-headers:["token,Origin, X-Requested-With, Content-Type, Accept"] access-control-allow-methods:["POST,GET,DELETE,PUT"] cache-control:["no-store, no-cache, must-revalidate"] connection:["Keep-Alive"] content-type:["application/json; charset=utf-8"] date:["Sun, 21 Oct 2018 14:02:20 GMT"] expires:["Thu, 19 Nov 1981 08:52:00 GMT"] keep-alive:["timeout=5, max=100"] request_code:["1"] msg:["登陸成功"] token:["xxxxxxxx"] pragma:["no-cache"] server:["Apache/2.4.23 (Win32) OpenSSL/1.0.2j mod_fcgid/2.3.9"] set-cookie:["PHPSESSID=6b0esq5jd8vloess2c96ove86s; path=/; HttpOnly"] transfer-encoding:["chunked"] x-powered-by:["PHP/7.2.1"]
以上參數中 msg
request_code
token
爲自定義參數 是服務器代碼生成的!
能獲得這些就好辦了!
渲染進程拿到header
中的token
根據 token
獲取用戶信息這以後就簡單的很了!!!
import {ipcMain, BrowserWindow, shell} from 'electron' ipcMain.on('qqLogin', (event, data) => { const loginWindow = new BrowserWindow({ width: 750, height: 450, resizable: false, minimizable: false, maximizable: false, webPreferences: { devTools: false, } }); loginWindow.setMenu(null); loginWindow.loadURL(data.url); loginWindow.webContents.on('new-window', (event, url) => { event.preventDefault(); shell.openExternal(url); }); const content = loginWindow.webContents; content.on('will-navigate', (e, status, url,) => { content.on('did-get-response-details', (e, status, url, originalURL, httpResponseCode, requestMethod, referrer, header) => { if (httpResponseCode === 200) { event.sender.send('reply', header); loginWindow.close(); } }) }); });
返回的header裏面是一個數組 這種寫法真是坑爹啊! 還要去寫一個 header.token[0]
這種寫法有點不喜歡 可是無法子!
來源:https://segmentfault.com/a/1190000016754668