求助:如何解析multipart/related响应并提取完好的.txt.gz附件
兄弟,我太懂你这种卡了一周的崩溃感了——处理这种带二进制附件的multipart响应确实容易踩坑,尤其是手动拆Buffer稍不注意就把文件搞坏了。咱们来一步步解决这个问题:
先分析你的响应结构
从你给出的res.headers和res.body能看出来,这是一个multipart/related格式的响应:
- 响应头里明确给出了分隔边界(boundary):
----=_Part_109_17473961.1526352793275 - 响应包含两个部分:第一个是SOAP XML返回体,第二个就是你要的
application/octet-stream类型的.gz附件,而且XML里的href="cid:xxx"正好对应附件的Content-Id,附件位置是明确的。
你之前手动拆分Buffer失败,大概率是因为没处理好多部分之间的换行符(\r\n)、边界前后的额外字符,或者字节截断——.gz文件对完整性要求极高,多/少一个字节都会直接损坏。
用专业库解析(避免手动踩坑)
直接用busboy这个库来处理multipart响应,它能自动帮你拆分各个部分,完美处理二进制数据:
步骤1:安装依赖
npm install busboy
步骤2:编写解析代码
假设你用request库已经拿到了响应的Buffer(res.body),可以这样处理:
const Busboy = require('busboy'); const fs = require('fs'); // 从响应头里正确提取边界(注意去掉引号) const boundary = res.headers['content-type'] .split('boundary=')[1] .replace(/"/g, ''); const busboy = new Busboy({ headers: res.headers, boundary: boundary }); // 监听文件部分的事件 busboy.on('file', (fieldname, file, filename, encoding, mimetype) => { // 这里的file是可读流,直接pipe到文件写入流 const writeStream = fs.createWriteStream('your_target_file.txt.gz'); file.pipe(writeStream); writeStream.on('finish', () => { console.log('附件提取完成!可以试试用gzip解压验证'); }); }); busboy.on('finish', () => { console.log('整个响应解析完成'); }); // 把响应的Buffer传给busboy处理 busboy.end(res.body);
更高效的流式处理(推荐)
如果文件比较大,建议直接用流式处理,不用先把整个Buffer存在内存里:
const request = require('request'); const Busboy = require('busboy'); const fs = require('fs'); const busboy = new Busboy({ // 可以在请求响应回来后动态设置headers,这里先示例固定值 headers: res.headers }); busboy.on('file', (fieldname, file, filename, encoding, mimetype) => { const writeStream = fs.createWriteStream('your_target_file.txt.gz'); file.pipe(writeStream); writeStream.on('finish', () => { console.log('流式提取附件完成!'); }); }); // 发起POST请求并直接pipe到busboy request.post({ uri: 'https://50.22.22.22:8443/logcollectionservice/services/DimeGetFileService', headers: { 'Authorization': 'Basic YWRt123123123123123123', 'SOAPAction': 'http://schemas.cisco.com/ast/soap/action/#LogCollectionPort#GetOneFile', 'content-length': 467 // 确保你的请求体长度和实际一致 }, body: // 这里传入你的POST请求体内容 }).pipe(busboy);
验证提取结果
提取完成后,用命令行试试解压:
gzip -d your_target_file.txt.gz
如果能正常解压出.txt文件,说明提取成功了。
内容的提问来源于stack exchange,提问作者Jeff Levensailor
相关产品推荐
相关产品推荐

