You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron v21升级后net.request周期性无法获取响应头求助

问题:Electron v21.0.1中net.request频繁无法获取响应头

问题背景

我需要连接服务器(如https://myserver/file.exe)检查文件新版本并执行更新,原本通过@electron/remote的net模块发起请求,从response.headers中获取last-modified头参数判断版本。

该功能在Electron 12.2.2中正常运行,但升级到v21.0.1后,频繁出现请求返回200状态码和数据,但响应头为空的情况,日志示例:

STATUS: 200
HEADERS: {}
data: Array(15)

仅约10%的请求能正常获取完整响应头,示例:

HEADERS: {"date":"Wed, 05 Oct 2022 12:22:42 GMT","etag":""633bc02a-aec01d"","last-modified":"Tue, 04 Oct 2022 05:10:02 GMT","cache-control":"max-age=3600","cf-cache-status":"REVALIDATED","report-to":"{"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v3?s=CkyxJliNOH9rDYgSVpjID7NaTVlUkBH1tgJxibvzmTh%2BRpZBk0FeFf03oJuHateoQVnWJhqSn1FHNs2%2FB%2Fkc%2BDuiaAnt%2BKHmzRlGoAY%2BGDplpVJ1K%2BXVDITGmD0xeFRXtA%3D%3D"}],"group":"cf-nel","max_age":604800}","nel":"{"success_fraction":0,"report_to":"cf-nel","max_age":604800}","vary":"Accept-Encoding","server":"cloudflare","cf-ray":"75561fd10c439b3d-FRA","alt-svc":"h3=":443"; ma=86400, h3-29=":443"; ma=86400"}

注:请求经过Cloudflare代理,用Postman发起相同请求始终能正常获取响应头。此问题导致无法依赖last-modified判断更新,完全破坏了更新逻辑,希望在不降级Electron的前提下找到原因和解决办法。

当前代码

const { net } = require('@electron/remote');

...

checkUpdate() {
    const request = net.request({
        method: 'GET',
        protocol: 'https:',
        hostname: <myUrl>,
        port: 443,
        path: <myPath>
    });
    
    request.setHeader('x-abs-abcore-version', '1.00');
    request.setHeader('x-abs-abcore-type', 'crossplatform');
    request.setHeader('Content-Type', 'application/x-www-form-urlencoded');
    
    request.on('response', (response) => {
    
        const data = []; 
    
        response.on('error', (e) => { 
            console.log(e);
        });
                    
        response.on('data', (chunk) => {
            data.push(chunk)
        });
    
        response.on('end', () => {                            
            console.log(`STATUS: ${response.statusCode}`)
            console.log(`HEADERS: ${JSON.stringify(response.headers)}`)
            console.log("data",data)

            if (Date.parse(<localFilesLastModified>) < Date.parse(response.headers['last-modified'].toString())) { 
                //Do some update
            }
                              
                              
        });

        request.on('error', (err) => {
            console.log(err)
        });
        
        request.end();
    });
}

可能原因与解决方案

1. 移除@electron/remote依赖,直接使用主进程的net模块

Electron从v14开始逐步弱化remote模块,v20+更是将其标记为废弃,使用remote的net可能存在兼容性问题。建议将请求逻辑移到主进程,通过IPC与渲染进程通信:

主进程代码示例:

const { net, ipcMain } = require('electron');

ipcMain.handle('check-update', async () => {
    return new Promise((resolve, reject) => {
        const request = net.request({
            method: 'GET',
            protocol: 'https:',
            hostname: <myUrl>,
            port: 443,
            path: <myPath>
        });
        
        request.setHeader('x-abs-abcore-version', '1.00');
        request.setHeader('x-abs-abcore-type', 'crossplatform');
        // GET请求无需设置Content-Type,可移除该行
        // request.setHeader('Content-Type', 'application/x-www-form-urlencoded');
        
        request.on('response', (response) => {
            const headers = response.headers;
            const data = [];

            response.on('data', (chunk) => data.push(chunk));
            response.on('end', () => resolve({ statusCode: response.statusCode, headers, data }));
            response.on('error', reject);
        });

        request.on('error', reject);
        request.end();
    });
});

渲染进程代码示例:

const { ipcRenderer } = require('electron');

async function checkUpdate() {
    try {
        const { statusCode, headers, data } = await ipcRenderer.invoke('check-update');
        console.log(`STATUS: ${statusCode}`);
        console.log(`HEADERS: ${JSON.stringify(headers)}`);
        
        if (headers['last-modified'] && Date.parse(<localFilesLastModified>) < Date.parse(headers['last-modified'])) {
            // 执行更新逻辑
        }
    } catch (err) {
        console.error(err);
    }
}

2. 修复冗余的请求头设置

当前代码为GET请求设置了Content-Type: application/x-www-form-urlencoded,这是不必要的,可能导致Cloudflare或服务器的异常处理,建议直接移除该行。

3. 禁用HTTP/3,强制使用HTTP/1.1或HTTP/2

Electron v21默认启用了HTTP/3支持,部分CDN(如Cloudflare)在HTTP/3下的响应头处理可能存在兼容性问题,可以强制关闭HTTP/3:

const { session } = require('electron');

const request = net.request({
    // ...其他配置
    session: session.fromPartition('no-http3', {
        network: {
            enableHttp3: false
        }
    })
});

4. 提前获取响应头,避免在end事件中读取

尝试在response回调中直接获取响应头,或监听headers事件,避免在end事件中可能出现的头丢失:

request.on('response', (response) => {
    // 直接在响应回调里获取headers
    console.log('HEADERS:', response.headers);
    
    // 或监听headers事件
    response.on('headers', (headers) => {
        console.log('HEADERS EVENT:', headers);
    });
    
    // ...其他逻辑
});

内容的提问来源于stack exchange,提问作者Gary Klasen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 10:30:28