基于chrome.sockets.tcpServer的Chrome应用如何发送图片等媒体文件?
解决方案
现有代码仅适用于文本类资源的核心问题是:你将响应头和资源内容拼接为字符串后再转ArrayBuffer的逻辑,在处理图片、音视频等二进制资源时,会因为字符串编码转义导致字节丢失,最终资源损坏无法正常渲染。
实现步骤
- 请求远程资源时直接获取原始二进制数据,不要做字符串转换
- 单独构建HTTP响应头并转成二进制格式
- 合并响应头二进制数据和资源二进制数据后直接发送
完整代码示例
// 工具方法:合并两个ArrayBuffer function concatArrayBuffer(buf1, buf2) { const merged = new Uint8Array(buf1.byteLength + buf2.byteLength); merged.set(new Uint8Array(buf1), 0); merged.set(new Uint8Array(buf2), buf1.byteLength); return merged.buffer; } // 通用发送响应方法,兼容文本、图片、音视频所有类型资源 function sendResponse(socketId, contentBuffer, contentType) { const sep = '\r\n'; // 构建响应头 const headerStr = [ 'HTTP/1.1 200 OK', 'Server: chrome24', `Content-Length: ${contentBuffer.byteLength}`, 'Connection: Close', `Content-Type: ${contentType}` ].join(sep) + sep + sep; // 响应头转二进制 const headerBuffer = new TextEncoder().encode(headerStr).buffer; // 合并得到完整响应数据 const fullBuffer = concatArrayBuffer(headerBuffer, contentBuffer); chrome.sockets.tcp.send(socketId, fullBuffer, (resultCode) => { console.log("数据发送完成,结果码:", resultCode); }); } // 调用示例:拉取远程图片并发送 fetch('你的远程资源地址') .then(res => Promise.all([ res.arrayBuffer(), // 直接拿二进制数据,不要用res.text() res.headers.get('Content-Type') // 透传原始资源类型,也可以手动指定 ])) .then(([fileBuffer, contentType]) => { sendResponse(info.clientSocketId, fileBuffer, contentType); });
注意事项
Content-Length必须取二进制数据的byteLength属性,不能使用字符串的length属性,否则会出现内容长度不匹配,导致浏览器截断资源或挂起请求- 不需要复用之前的
string2ArrayBuffer方法,Chrome原生支持的TextEncoder编码更稳定,不会出现乱码问题 - 如果是本地静态资源,手动指定对应Content-Type即可,比如png图片填
image/png、mp4视频填video/mp4、jpeg图片填image/jpeg
内容的提问来源于stack exchange,提问作者Harkal
相关产品推荐
相关产品推荐

