electron实现qq快捷登录的方法示例
之前本来想不写这个功能的,结果客户死活要qq登录! 实在没办法就写了,顺便写个文章!
在写之前有两个问题:
1: 打开qq授权页面点击页面中的链接会又打开一个页面! .....
2: 授权之后是否成功很难去判断
不过脑海中有一个想法就是,electron就是一个类似于浏览器一样,既然是浏览器那肯定可以阻止链接的点击 也可以判断状态!
就去啃文档了!!!
推荐大家去w3c去看文档 比较全 而且速度较快 文档也比较新:https://www.w3cschool.cn/electronmanual/
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({ 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]
这种写法有点不喜欢 但是没法子!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
- 使用nginx代理跨域,使用nginx代理bing的每日一图
- Java Web基础入门
- Java中Optional使用注意事项
- 使用awk来解析dump文件 (73天)
- IntelIj IDEA运行JUnit Test OutOfMemoryError
- git pull fails “unable to resolve reference” “unable to update local ref”
- 使用dropwizard(5)--加入swagger
- 使用hint来调优sql语句(72天)
- 用R语言对城管事件数据分析
- 使用dropwizard(4)-加入测试-jacoco代码覆盖率
- goldengate学习-安装篇(71天)
- 使用dropwizard(6)-国际化-easy-i18n
- 配置不同环境下启用swagger,在生产环境关闭swagger
- 使用ControllerAdvice注意事项,Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Js 删除 指定Domin 指定 path 下的 cookie中指定的内容
- 适配器模式与装饰器模式的区别
- java堆内存详解
- springBoot 入门(一)—— 使用idea创建第一个springBoot项目
- “dddb超级”工具包——高效、快速开发JavaWeb项目后端结构
- 在Java Web中设计的编解码
- 怎么让用一行代码实现页面的定时强制刷新?脚本刷流量再也不用愁了!
- 什么是Javac
- springBoot 入门(二)—— 使用 spring.profiles.active来区分配置
- Kubernetes 1.19.0——deployment(2)
- JavaWeb新手进阶经典项目 & 半小时高效开发 & 海量知识点涵盖 (二)
- Java web 开发 Session超时设置
- JavaWeb第四讲 会话跟踪技术HttpSession、Cookie、url、隐藏表单域
- springBoot 入门(三)—— 使用 RestController
- SSM第一讲 Spring概述和基础知识详解