zoukankan      html  css  js  c++  java
  • electron实现qq快捷登录!

    之前本来想不写这个功能的,结果客户死活要qq登录! 实在没办法就写了,顺便写个文章!
    在写之前有两个问题:
    1: 打开qq授权页面点击页面中的链接会又打开一个页面! .....
    2: 授权之后是否成功很难去判断

    不过脑海中有一个想法就是,electron就是一个类似于浏览器一样,既然是浏览器那肯定可以阻止链接的点击 也可以判断状态!
    就去啃文档了!!!

    推荐大家去w3c去看文档 比较全 而且速度较快 文档也比较新: https://www.w3cschool.cn/elec...

    https://electronjs.org/docs 这里面的响应速度比较慢 里面很多文档都很久了 参数也有失效的!!!

    言归正传 说qq登录!

    后端是使用PHP实现的 没什么难度,主要的就是客户端的一些处理!

    演示

    放置qq登录按钮

    
    <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>
    

    问题解决

    点击a链接会打开一个新窗口

    解决打开qq授权页面点击页面中的链接会又打开一个窗口的问题 使用webContents 的 new-window 事件 组织默认事件 调用Shell利用默认浏览器打开就行了!

    
       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({
             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
  • 相关阅读:
    HTTP协议【详解】——经典面试题
    原生JS的地区二级联动,很好理解的逻辑
    js操作字符串的常用方法
    移除input框type="number"在部分浏览器的默认上下按钮
    atom
    解决gitHub下载速度慢的问题
    ATOM常用插件推荐
    脚踝扭伤肿了怎么办
    这才是真正的电子科大
    月入 7000,怎么存钱?
  • 原文地址:https://www.cnblogs.com/datiangou/p/10130458.html
Copyright © 2011-2022 走看看