背景

最近在做一个Web和Electron共用一份代码的工程,由于使用到了第三方的库(我们是在线地图),该库的认证方式是请求时加key,并且它在后台会校验referer。

于是问题就来了,Electron是运行在本地的,http请求的时候,是不会带有授权Web站点的referer的。导致认证失败,无法调用所需的api接口。

分析

既然HTTP请求发送的时候不带referer,那么我们给他加上去,是不是就可以了呢?

对策

方法1:自定义HTTP协议,在发送请求时,补上referer

// 注册自定义协议
protocol.registerStandardSchemes(['app', '自定义协议'], { secure: true })
// 自定义协议的具体实现
protocol.registerHttpProtocol('自定义协议', (req, cb) => {
cb({
url: “特定的url地址”,
referrer: "http://被授权的referrer头信息"
})
})
// 发送请求时可以使用 自定义协议://url地址 的形式来发送请求
发送请求时可以使用 自定义协议://url地址 的形式来发送请求。当然,我们这个例子里面只是追加了referrer,其实根据实际需求还可以做很多其它事情。
相关api文档:https://electronjs.org/docs/api/protocol#protocolregisterhttpprotocolscheme-handler-completion

方法2:修改窗口会话中发送请求前的行为

本来以为方法1以及很完美的解决了问题,但是,在自定义协议认证成功后,在api的使用过程中,api内部主动发送了http请求,这时的api请求没有使用自定义协议,再次认证失败了。于是我想到有个办法,很天真的认为可以解决问题。失败的做法如下:

    protocol.interceptHttpProtocol("http", (req, cb) => {
// 此处可以追加url是否匹配的逻辑判断
cb({
url:req.url,
referrer: "http://授权的referrer头信息"
})
})
相关api文档:https://electronjs.org/docs/api/protocol#protocolintercepthttpprotocolscheme-handler-completion

我直接拦截了原生的http协议,追加referrer信息,发生的结果是,http->截获http->修改后发送http->截获http->修改后发送http->......发生了无限循环!!!

于是只能另辟蹊径,寻找其余解决方案。发现了webquest的行为可以捕获。于是在onBeforeSendHeaders的时机,追加Referer信息。正确的做法如下:

   // 需要拦截的URL地址
const xxx_filter = {
urls: ["https://*.xxx.com/*", "http://*.yyy.com/*"]
}
session.defaultSession.webRequest.onBeforeSendHeaders(xxx_filter, (details, callback) => {
details.requestHeaders['Referer'] = 'http://授权的referer头信息'
callback({ requestHeaders: details.requestHeaders });
})
相关api文档:https://electronjs.org/docs/api/web-request

总结

通过对webrequest的捕获,解决了本次的问题,并且把自定义协议那个案也可以替换掉。webrequest还有好几个阶段的行为可以自定义,可以适用于不同场景的需求。

Electron使用时拦截HTTP请求的解决方案的更多相关文章

  1. LigerUI中Grid的使用时关于url请求不到数据的问题

    前台代码:(这里贴的是js的代码,完整的代码可以在LigerUI的文档中找到), 这里使用的是url请求数据,问题不是处在前台,所以就不细说. $("#maingrid").lig ...

  2. SpringData JPA框架使用时出现JSON循环依赖解决方案

    困扰许久的问题终于解决了,之前项目太赶,没有深入学习解决,不甘心,今天再次搭起架子试试,哈哈,终于解决! @ManyToOne(cascade={CascadeType.MERGE,CascadeTy ...

  3. MySQL 安装和启动服务,“本地计算机 上的 MySQL 服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止。”

    MySQL 安装和启动服务,以及遇到的问题 MySQL版本: mysql-5.7.13-winx64.zip (免安装,解压放到程序文件夹即可,比如 C:\Program Files\mysql-5. ...

  4. Netty4.0.24.Final 版本中 IdleStateHandler 使用时的局限性

    使用Netty在客户端和服务端建立通讯通道,一般来说,一个连接可能很久没有访问,由于各种各样的网络问题导致连接已经失效,客户端再次发送请求时会产生连接异常. 基于这个原因,需要在客户端和服务端之间建立 ...

  5. Saiku嵌入系统使用时传参数访问saiku(十六)

    Saiku嵌入系统使用时传参数访问saiku Saiku通过iframe嵌入其他系统使用时,我们可以设定参数信息,然后根据url中参数对结果进行筛选哦. 这里我们实现的是根据日期字段进行范围查询,UR ...

  6. Saiku多用户使用时数据同步刷新(十七)

    Saiku多用户使用时数据同步刷新 这里我们需要了解一下关于saiku的刷新主要有两种数据需要刷新: >1 刷新数据库的表中的数据,得到最新的表数据进行展示. >2 刷新cube信息,得到 ...

  7. 本机mysql 5.7服务启动后停止,某些服务在未有其他应用程序使用时停止

    本机mysql 5.7服务启动后停止,某些服务在未有其他应用程序使用时停止 出现这种报错,mysql服务启动不了: 错误的尝试: 1:尝试了这个博客:https://blog.csdn.net/wai ...

  8. Promise使用时应注意的问题

    最近在使用axios库时遇到了个问题,后端接口报了500错误,但前端并未捕获到.1. 调用接口的业务代码如下: // 业务代码调用 axios({ url: url, method: 'post', ...

  9. 关于homebrew使用时遇到的问题: Error: Could not symlink bin/gdb/usr/local/bin is not writable.

    # 关于homebrew使用时遇到的问题: Error: Could not symlink bin/gdb/usr/local/bin is not writable. 这是我在给我的Mac电脑安装 ...

随机推荐

  1. 源码包安装转换rpm包

    目录 纯净版虚拟机 1. 先安装个虚拟机,登陆nginx官网 http://nginx.org/选择一个稳定的版本 2. 右键复制地址,到新克隆的纯净虚拟机wget 下载 3.源码包 4.解压 tar ...

  2. bayaim_hadoop1_2.2.0伪分布式搭建

    ------------------bayaim_hadoop1_2.2.0伪分布式搭建_2018年11月06日09:21:46--------------------------------- 1. ...

  3. MySQL 部署分布式架构 MyCAT (五)

    分片(水平拆分) 4.全局表 业务使用场景: 如果你的业务中有些数据类似于数据字典,比如配置文件的配置, 常用业务的配置或者数据量不大很少变动的表,这些表往往不是特别大, 而且大部分的业务场景都会用到 ...

  4. oracle数据库不小心删除了数据

    1.select * from SYS_DICT as of timestamp to_timestamp('2019-11-05 10:00:00','yyyy-mm-dd hh24:mi:ss') ...

  5. [视频教程] 使用docker的方式安装redis

    直接使用docker拉取redis的镜像,并且进行端口映射与文件目录共享,这样可以直接在宿主机的端口上就可以进行访问了.其实本质上也是在一个简化版的ubuntu的容器内安装好的redis-server ...

  6. centos 7下配置阿里yum源

    1.打开centos的yum文件夹 cd /etc/yum.repos.d/ 2.用wget下载repo文件 wget http://mirrors.aliyun.com/repo/Centos-7. ...

  7. selenium python 脚本不支持中文问题

    在 python shell 中执行以下脚本: ...... dr.find_element_by_xpath("//a[test()='查看']") ...... 点击 Run ...

  8. TCP协议如何保证可靠传输

    TCP协议如何保证可靠传输 概述: TCP协议保证数据传输可靠性的方式主要有: (校 序 重 流 拥) 校验和: 发送的数据包的二进制相加然后取反,目的是检测数据在传输过程中的任何变化.如果收到段的检 ...

  9. SpringBoot与SpringMVC的区别是什么?

    感谢原文出处:https://www.cnblogs.com/javazhiyin/ Spring 框架就像一个家族,有众多衍生产品例如 boot.security.jpa等等.但他们的基础都是Spr ...

  10. jQuery中的事件(七)

    1. ready(fn), 当DOM载入就绪可以查询及操纵时绑定一个要执行的函数 这个方法纯粹是对向window.load事件注册事件的替代方法.通过使用这个方法,可以在DOM载入就绪能够读取并操纵时 ...