Electron?網(wǎng)絡(luò)攔截實(shí)戰(zhàn)示例詳解
正文
Electron 提供的 webRequest API,允許開發(fā)者對網(wǎng)絡(luò)進(jìn)行過濾和監(jiān)聽,并且可以修改 header 字段甚至請求地址,功能非常強(qiáng)大,它的類結(jié)構(gòu)如下:
不過需要注意,該模塊只能在主進(jìn)程中使用,接下來為大家介紹 webRequest 三個(gè)非常典型的使用場景:
自定義 UA
有些接口為了過濾非法請求,會(huì)首先校驗(yàn) UserAgent,正常的瀏覽器是無法偽造 UA 的,不過在 Electron 里面可以很容易做到,webRequest 模塊提供的 onBeforeSendHeaders
方法能夠?qū)τ蛎M(jìn)行過濾,攔截即將發(fā)出去的請求頭,修改之后再真正的發(fā)出去。例如下面的代碼會(huì)在訪問 github 相關(guān)域名的時(shí)候,把 header 中的 User-Agent 字段修改為 MyAwesomeAgent:
const { session } = require('electron') const filter = { urls: ['https://*.github.com/*'] } session.defaultSession.webRequest.onBeforeSendHeaders(filter, (details, callback) => { details.requestHeaders['User-Agent'] = 'MyAwesomeAgent' callback({ requestHeaders: details.requestHeaders }) })
繞過跨域限制
使用 Electron 加載第三方網(wǎng)站的時(shí)候,默認(rèn)行為和 Chrome 是一致的,都會(huì)受到同源策略的影響,為了驗(yàn)證,我們首先加載本地 3020 端口上的靜態(tài)文件:
win = new BrowserWindow({ width: 600, height: 400 }) win.loadURL('http://localhost:3020') win.webContents.toggleDevTools({ mode: 'bottom' })
然后在 3030 端口上啟動(dòng)一個(gè) http 服務(wù):
const Koa = require('koa') const app = new Koa() app.use((ctx, next) => { ctx.body = { success: true, } }) app.listen(3030)
此時(shí)在控制臺(tái)請求 3030 端口上的服務(wù),會(huì)發(fā)現(xiàn)典型的跨域報(bào)錯(cuò),果不其然被 cors 策略拒絕了:
了解跨域原理的同學(xué)都知道,其實(shí)網(wǎng)絡(luò)請求是已經(jīng)回來了,但是瀏覽器會(huì)檢查 response header 里面的 Access-Control-Allow-Origin
,如果當(dāng)前域名不在里面,就 block 這個(gè)響應(yīng),如下圖所示:
要想讓瀏覽器不 block 響應(yīng)的話,傳統(tǒng)的解決方案一般有兩種:
- 讓后端添加
Access-Control-Allow-Origin
,支持當(dāng)前的 Origin - 用 node 做本地代理來轉(zhuǎn)發(fā)請求
而在 Electron 里面,又多了一種方案,因?yàn)?Electron 可以對網(wǎng)絡(luò)請求進(jìn)行攔截,任意修改請求或響應(yīng)的 header,那么只要把響應(yīng)標(biāo)頭里面的 Access-Control-Allow-Origin
改掉不就好了么:
代碼如下:
const filter = { urls: ['http://localhost:*/*'], } win.webContents.session.webRequest.onHeadersReceived(filter, (details, callback) => { const { responseHeaders } = details responseHeaders['Access-Control-Allow-Origin'] = ['*'] callback({ responseHeaders }) })
打開網(wǎng)絡(luò)面板觀察網(wǎng)絡(luò)請求,響應(yīng)標(biāo)頭里面就有 Access-Control-Allow-Origin
了,成功繞過 cors 校驗(yàn):
請求轉(zhuǎn)發(fā)
通過 webRequest API,可以將發(fā)到接口 A 的請求轉(zhuǎn)發(fā)到接口 B。為了驗(yàn)證這個(gè)能力,我們寫了一個(gè) http 服務(wù),同時(shí)監(jiān)聽 3030 和 4040 端口,并響應(yīng) JSON 數(shù)據(jù),里面包含了 port 字段表示當(dāng)前請求到了哪個(gè)端口:
const http = require('http') const URL = require('url') function listen(port) { http .createServer((req, res) => { const { url, method, headers } = req const { query, pathname } = URL.parse(url, true) res.setHeader('Content-Type', 'application/json') res.end(JSON.stringify({ method, pathname, query, headers, port })) }) .listen(port) } listen(3030) listen(4040)
然后通過 onBeforeRequest
方法進(jìn)行攔截:
win.webContents.session.webRequest.onBeforeRequest( { urls: ['http://localhost:3030/*'], }, (details, callback) => { callback({ redirectURL: 'http://localhost:4040' }) }, )
在控制臺(tái)發(fā)送 3030 端口請求,結(jié)果返回了 4040 端口的數(shù)據(jù):
這個(gè)能力非常強(qiáng)大,例如可以做下面的事情:
- 后端接口未部署之前,前端自己做本地接口 mock
- 把某個(gè)頁面的 js 攔截掉,換成自己的 js 來調(diào)試
- 故意請求一個(gè)不存在的地址,然后僅對授權(quán)用戶轉(zhuǎn)發(fā)到真實(shí)地址
以上就是Electron 網(wǎng)絡(luò)攔截實(shí)戰(zhàn)示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Electron 網(wǎng)絡(luò)攔截的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
微信小程序 保留小數(shù)(toFixed)詳細(xì)介紹
這篇文章主要介紹了 微信小程序 保留小數(shù)(toFixed)詳細(xì)介紹的相關(guān)資料,這里附有實(shí)例,幫助大家學(xué)習(xí)參考此部分知識(shí),需要的朋友可以參考下2016-11-11JavaScript獲取上傳文件相關(guān)信息示例詳解
這篇文章主要為大家介紹了JavaScript獲取上傳文件相關(guān)信息示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08