webContents.session.webRequest.onBeforeSendHeaders(filter, (details, callback) => { details.url = details.url.replace("www.xuexiluxian.cn", "www.xuexiluxian.cn:9999") details.requestHeaders['WechatOauthType'] = 'login' if ( token ) { details.requestHeaders['WechatOauthType'] = 'bind' details.requestHeaders['Authorization'] = token } callback({requestHeaders: details.requestHeaders}) })
时间: 2024-04-20 18:26:33 浏览: 125
这段代码是用于在发送网络请求前修改请求头的内容和URL。具体流程如下:
1. 首先,通过`webContents.session.webRequest.onBeforeSendHeaders`方法监听网络请求的发送事件。
2. 当有网络请求即将发送时,会触发回调函数,并传入参数`details`和`callback`。
3. 在回调函数中,首先通过`details.url.replace()`方法将URL中的"www.xuexiluxian.cn"替换为"www.xuexiluxian.cn:9999",从而修改了请求的目标地址。
4. 接着,设置了请求头中的"WechatOauthType"字段为"login",表示请求类型为登录。
5. 如果存在`token`变量的值,说明已经登录成功,那么将"WechatOauthType"字段设置为"bind",表示请求类型为绑定,并添加了"Authorization"字段并赋值为`token`,用于身份验证。
6. 最后,通过`callback()`方法回传修改后的请求头信息。
总而言之,这段代码的作用是在发送网络请求前,修改请求头的内容和URL,并添加相应的字段进行身份验证。
相关问题
wxWindow.webContents.on('will-navigate', (e) => { const webContents = wxWindow.webContents // // 过滤url地址,只监听需要的url const filter = {urls: ['*://www.xuexiluxian.cn/oauth/*']} webContents.session.webRequest.onBeforeSendHeaders(filter, (details, callback) => { details.url = details.url.replace("www.xuexiluxian.cn", "www.xuexiluxian.cn:9999") details.requestHeaders['WechatOauthType'] = 'login' if ( token ) { details.requestHeaders['WechatOauthType'] = 'bind' details.requestHeaders['Authorization'] = token } callback({requestHeaders: details.requestHeaders}) }) //请求完成 webContents.session.webRequest.onCompleted(filter, (details) => { const params = new URLSearchParams(new URL(details.url).search) const code = params.get("code") // 1. 通知渲染进程 // a.绑定:调接口 if ( token ) { api.window.webContents.send('main-to-renderer', { name: 'wechat-bind', event: 'event', data: code }) } else { // b.登录:调接口 ==> 主进程给渲染进程通信 api.window.webContents.send('main-to-renderer', { name: 'wechat-login', event: 'event', data: code }) } // 2. 关闭当前窗体 wxWindow.close() // 3. 销毁当前窗体 wxWindow.destroy() }) })
这段代码是在wxWindow的webContents上注册了两个事件监听器,用于处理将要导航和请求完成的情况。
1. 首先,在wxWindow的webContents上监听了"will-navigate"事件,该事件在页面即将导航到新URL时触发。
2. 在"will-navigate"事件的回调函数中,创建了一个URL过滤器对象filter,用于指定需要监听的URL地址,这里只监听形如"https://www.xuexiluxian.cn/oauth/*"的URL。
3. 接着,通过webContents.session.webRequest.onBeforeSendHeaders方法,在发送网络请求前注册了一个回调函数。该回调函数会在每次请求发送前被调用。
4. 在回调函数中,首先通过details.url.replace()方法将URL中的"www.xuexiluxian.cn"替换为"www.xuexiluxian.cn:9999",从而修改了请求的目标地址。
5. 然后,根据条件判断是否存在token变量。如果存在,说明已经登录成功,将"WechatOauthType"字段设置为"bind",并添加了"Authorization"字段并赋值为token,用于身份验证。
6. 在请求完成后,通过webContents.session.webRequest.onCompleted方法注册了一个回调函数。该回调函数会在每次请求完成后被调用。
7. 在回调函数中,首先从URL中获取code参数的值。
8. 根据条件判断是否存在token变量。如果存在,表示已经登录成功,通过api.window.webContents.send方法向渲染进程发送消息,通知进行绑定操作,同时将code作为数据传递给渲染进程。
9. 如果不存在token变量,表示需要进行登录操作,同样通过api.window.webContents.send方法向渲染进程发送消息,通知进行登录操作,并将code作为数据传递给渲染进程。
10. 最后,关闭当前窗口和销毁当前窗口。
总而言之,这段代码的作用是在wxWindow的webContents上监听页面导航和请求完成事件,根据条件进行URL的修改和请求头的设置,并向渲染进程发送消息通知执行相应的操作,最后关闭和销毁窗口。
for (var i=0;i<dataArray.length;i++) { var timenow=Date.now();//调用的时候,打个时间戳 const options = { directory: downloadPath, filename: dataArray[i].title + '.' + dataArray[i].fileType, saveAs: false, extension: dataArray[i].fileType, openFolderWhenDone: false, showProgressBar: true, showBadge: true, }; var downloader = new Downloader(dataArray[i], options); downloader.data.timeid=timenow;//存储唯一标识 downloader.start(); downloader.onStart = () => { // 下载开始 handleDownload.push(downloader); mainWindow.webContents.send('consolelog2', '检查代码在此执行次数'); }; downloader.onTotalProgress = (progress) => { // 更新下载进度 downloadArray.set(downloader.data.timeid, { title: downloader.data.title, sUrl: downloader.data.sUrl, progress: downloader.data.progress, size: downloader.data.size, status:downloader.data.status, timeid:downloader.data.timeid }); mainWindow.webContents.send('consolelog', downloadArray); mainWindow.webContents.send('donwloadStatus', true); }; downloader.onCompleted = () => { if(downloader.data.progress==100&&downloader.data.status=='process'){ mainWindow.webContents.send('endDownload', JSON.stringify(downloader)); mainWindow.webContents.send('donwloadStatus', false); downloader.data.status='complete' } if(downloader.data.progress<100){ mainWindow.webContents.send('donwloadStatus', true); } mainWindow.webContents.send('consolelog', downloadArray); }; } return JSON.stringify(dataArray); // 返回值将作为 Promise 的 resolved 值 }); 这段代码中,如果我是多个下载器,var downloader = new Downloader(dataArray[i], options); 这里就会导致重复创建一个名字的下载,导致我操作 downloader.start(); 的时候,会触发多个下载器的 start ,我要怎么优化。把下载器分离出独立
可以将 Downloader 类提取出来,单独作为一个模块,然后在循环中实例化多个 Downloader 对象,这样就可以避免重复创建相同名字的下载器。示例代码如下:
1. 创建 Downloader 类的模块 downloader.js:
```javascript
const request = require('request');
const fs = require('fs');
const path = require('path');
class Downloader {
constructor(data, options) {
this.data = data;
this.options = options;
this.req = null; // request 对象
this.writeStream = null; // 文件写入流
}
start() {
const { sUrl } = this.data;
const { directory, filename, saveAs, extension } = this.options;
const filePath = path.join(directory, saveAs ? filename : `${Date.now()}.${extension}`);
this.writeStream = fs.createWriteStream(filePath);
this.req = request
.get(sUrl)
.on('error', (err) => {
console.error(`请求 ${sUrl} 出错:${err.message}`);
this.data.status = 'failed';
})
.on('response', (response) => {
if (response.statusCode === 200) {
this.data.size = parseInt(response.headers['content-length'], 10);
} else {
this.data.status = 'failed';
}
})
.on('data', (chunk) => {
this.writeStream.write(chunk);
this.data.progress = (this.writeStream.bytesWritten / this.data.size) * 100;
})
.on('end', () => {
this.writeStream.end();
this.data.progress = 100;
this.data.status = 'complete';
});
}
pause() {
if (this.req) {
this.req.pause();
}
if (this.writeStream) {
this.writeStream.close();
}
}
resume() {
this.start();
}
cancel() {
this.pause();
const { directory, saveAs, extension } = this.options;
const filePath = path.join(directory, saveAs ? this.data.filename : `${Date.now()}.${extension}`);
fs.unlink(filePath, (err) => {
if (err) {
console.error(`删除文件 ${filePath} 出错:${err.message}`);
}
});
}
}
module.exports = Downloader;
```
2. 修改原来的代码,引入 downloader.js 模块,并实例化多个 Downloader 对象:
```javascript
const Downloader = require('./downloader');
...
for (let i = 0; i < dataArray.length; i++) {
const timenow = Date.now();
const options = {
directory: downloadPath,
filename: dataArray[i].title + '.' + dataArray[i].fileType,
saveAs: false,
extension: dataArray[i].fileType,
openFolderWhenDone: false,
showProgressBar: true,
showBadge: true,
};
const downloader = new Downloader(dataArray[i], options);
downloader.data.timeid = timenow;
downloader.start();
handleDownload.push(downloader);
downloader.onTotalProgress = (progress) => {
downloadArray.set(downloader.data.timeid, {
title: downloader.data.title,
sUrl: downloader.data.sUrl,
progress: downloader.data.progress,
size: downloader.data.size,
status: downloader.data.status,
timeid: downloader.data.timeid
});
mainWindow.webContents.send('consolelog', downloadArray);
mainWindow.webContents.send('donwloadStatus', true);
};
downloader.onCompleted = () => {
if (downloader.data.progress === 100 && downloader.data.status === 'process') {
mainWindow.webContents.send('endDownload', JSON.stringify(downloader));
mainWindow.webContents.send('donwloadStatus', false);
downloader.data.status = 'complete';
}
if (downloader.data.progress < 100) {
mainWindow.webContents.send('donwloadStatus', true);
}
mainWindow.webContents.send('consolelog', downloadArray);
};
}
```
阅读全文