
Electron 中 UploadData 对象详解请求上传体的结构定义、API 使用与源码实现【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electronElectron 的UploadData对象是网络栈向 JS 层暴露正在上传的请求体的标准数据结构主要出现在webRequest事件细节与协议处理相关的结构中。读懂它的三个字段、弄清楚它在session.webRequest监听器中的出现位置并对照 源码转换器 了解 Chromium 底层四种上传元素是如何映射成 JS 对象的你就能在拦截请求时准确识别普通字节、磁盘文件、Blob 和流式上传这四类载荷。UploadData 对象官方定义与字段语义UploadData 官方结构定义 非常紧凑全文只有三个字段这里完整继承并展开说明字段类型是否可选说明bytesBuffer必填正在发送的内容Content being sentfilestring可选正在上传的文件路径Path of file being uploadedblobUUIDstring可选Blob 数据的 UUID配合 ses.getBlobData 方法取回实际数据三个字段分别对应三种典型的上传场景bytes请求体在内存中、可以直接以Buffer形式读取时例如fetch上传字符串/ArrayBuffer转换器会把底层字节复制成 JS Buffer 挂到该字段上file上传的是一段磁盘文件例如multipart/form-data中通过File从fs路径构造的部分时JS 层拿到的只是文件路径字符串文件内容并不会被整体拷贝进内存blobUUID上传数据来自 BlobDataPipe 形式时对象上只携带一个 UUID 标识符需要通过session实例的ses.getBlobData(identifier)方法按标识取回数据——这一点在官方文档中作为blobUUID字段的说明被明确写出。UploadData 出现的位置webRequest 事件中的details.uploadDataWebRequest 模块文档 中uploadData以UploadData[]数组形式出现在两个监听器的details对象里webRequest.onBeforeRequest([filter, ]listener)details.uploadData为[UploadData[]](docs/api/structures/upload-data.md)非可选文档原文明确写道 The uploadDatais an array ofUploadDataobjects。该事件在请求即将发出时触发监听器必须通过callback返回一个含cancel、redirectURL等可选字段的 response 对象。webRequest.onBeforeSendHeaders([filter, ]listener)details.uploadData为[UploadData[]](docs/api/structures/upload-data.md)可选因为并非所有请求都带上传体此时details中还会附带requestHeaders适合在发头阶段检查上传内容并改写请求头。两个监听器都支持通过WebRequestFilter按 URL 过滤文档给出的合法 URL 模式 包括all_urls http://foo:1234/ http://foo.com/ *://*/* *://example.com/* http://*.foo:1234/ file://foo:1234/barProtocolRequest 结构中的可选uploadDataProtocolRequest 结构 定义了描述一次请求的对象url、referrer、method、headers以及可选的uploadData字段其类型同样是UploadData[]。也就是说在协议处理的请求描述中上传体同样以 UploadData 数组的形式暴露给嵌入方。源码实现Chromium 上传数据如何变成 UploadData从源码结构看UploadData并不是 Electron 自己构造的数据而是 Chromium 网络栈请求体对象的 JS 投影。关键转换逻辑位于 Converternetwork::ResourceRequestBody::ToV8它遍历底层network::ResourceRequestBody的elements()按DataElement::Tag枚举逐一分发构造出 JS 对象数组。四种底层元素到 JS 字段的映射关系如下见 net_converter.cc底层 mojom 元素type字段写入的 JS 属性kFileDataElementFilefilefile、filePath、offset、length、modificationTimekBytesDataElementBytesrawDatabytes通过electron::Buffer::Copy拷贝字节kDataPipeBlobblobblobUUID、dataPipekChunkedDataPipe流streambodyReadableStream包装可以推断出几个文档未展开、但源码中明确存在的事实文档字段是简化视图。官方结构文档只列了bytes/file/blobUUID三个字段而转换器实际还会写入type以及文件元素的filePath、offset、length、modificationTime。type字段取值file/rawData/blob/stream可以看作区分四种载荷的判断依据。字节拷贝发生在转换时。kBytes分支调用electron::Buffer::Copy意味着bytesBuffer 是底层数据的一份副本而kFile分支只传递路径不触发内容读取对大文件上传的拦截检查只读路径、校验文件名等是零拷贝的。Blob 的数据管道生命周期绑定在 UploadData 对象上。源码注释写道 The lifetime of data pipe is bound to the uploadData object即dataPipe属性DataPipeHolder与uploadData对象同生命周期——如果你要异步处理 Blob 数据需要保证持有该uploadData对象或及时用getBlobData取回内容。getBlobData有被重构的意图。源码中的 TODO 注释 表明在 NetworkService 重构之后旧的blobUUIDAPI 变得不必要地复杂未来计划弃用getBlobData并直接返回DataPipeHolder包装器。因此在使用blobUUID时宜将其视为稳定的当前 API但不必为它设计过度复杂的持久化方案。通过 getBlobData 取回 Blob 内容对携带blobUUID的 UploadData官方文档给出的取数方式是ses.getBlobData(identifier)其定义位于 Session API 文档。典型的使用链路是webRequest监听器拿到details.uploadData中某个元素的blobUUID→ 调用对应session的getBlobData→ 按 UUID 换回 Blob 数据。对于file元素则直接根据file路径用fsAPI 处理即可。与相近结构的区分仓库中还有几个容易与UploadData混淆的结构注意它们的适用场景不同UploadRawData / UploadFile{type: rawData, bytes}与{type: file, filePath, offset, length, modificationTime}两种结构是 PostBody 对象 中data数组的元素类型。PostBody含contentType、boundarycontentType只允许application/x-www-form-urlencoded或multipart/form-data对应 HTML 表单的enctype用于表单提交场景与UploadData的网络栈来源是两条不同的暴露路径ProtocolResponseUploadData只有contentTypeMIME 类型与datastring | Buffer两个字段出现在 ProtocolResponse 中属于协议处理器侧的上传响应数据与请求拦截侧的UploadData不是一回事。实战示例在 webRequest 中检查上传内容结合上述结构定义一个合法的拦截检查逻辑如下字段取值与 UploadData 定义、webRequest 事件细节 完全对应const { session } require(electron) const ses session.defaultSession ses.webRequest.onBeforeRequest( { urls: [*://*/*] }, (details, callback) { for (const chunk of details.uploadData) { if (chunk.file) { // 磁盘文件上传只拿到路径按需再读文件 console.log(file upload:, chunk.file) } else if (chunk.blobUUID) { // Blob 上传用 UUID 异步取回数据 ses.getBlobData(chunk.blobUUID).then(data { console.log(blob data size:, data.length) }) } else if (chunk.bytes) { // 内存中的原始字节 console.log(raw bytes:, chunk.bytes.length) } } callback({}) } )注意onBeforeRequest中uploadData是必填字段而onBeforeSendHeaders中它是可选的后者使用时应先做空值判断。小结UploadData由bytesBuffer必填、filestring可选、blobUUIDstring可选三字段组成分别覆盖内存字节、磁盘文件、Blob 三类上传内容它主要出现在webRequest的onBeforeRequest/onBeforeSendHeaders细节与ProtocolRequest结构中以数组形式暴露从源码看它由 net_converter.cc 将 Chromium 的ResourceRequestBody四种DataElementfile / rawData / blob / stream转换而来实际对象上还带有type等文档未列出的字段取回 Blob 数据使用ses.getBlobData(identifier)与PostBody、ProtocolResponseUploadData等相似结构应明确区分场景后再使用。【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考