Electron使用时拦截HTTP请求的解决方案

Stella981
• 阅读 1152

背景

最近在做一个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还有好几个阶段的行为可以自定义,可以适用于不同场景的需求。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
java中比较两个时间的差值
项目背景1.某篇文稿的发布时间是publishDate,例如:2020072118:00:41。2.现要求判断该篇文稿的发布时间是否在近30天之内。publicstaticlongdayDiff(DatecurrentDate,DatepublishDate){LongcurrentTimecurrentDat
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Easter79 Easter79
3年前
SpringMvc接受特殊符号参数被转义
WEB开发时,在前端通过get/post方法传递参数的时候 如果实参附带特殊符号,后端接收到的值中特殊符号就会被转义例如该请求: http://localhost:10001/demo/index.do?name张三(1)注:中文()不会出现此种情况后台就收到的实际name值为:  张三&40;1&41;&40;其实为h
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这