【问题标题】:What is the best way to parse a multipart/mixed response executed with Axios in NodeJS?在 NodeJS 中解析使用 Axios 执行的多部分/混合响应的最佳方法是什么?
【发布时间】:2021-08-05 13:35:20
【问题描述】:

现在已经好几天了,我被困在我认为应该是一个简单的问题来解决......

我有一个 nodeJS express 应用程序,它根据对特定路由的请求,向外部服务发出带有有效负载的 AXIOS 发布请求。 此服务确实以多部分/混合内容类型(标题中提到内容类型)进行响应。 响应包含一个 PDF 和一个带有信息的 JSON。

我在 AWS S3 上成功地将 response.data 完全保存为 PDF。 但我无法找到至少一种方法来解析 response.data 以提取我需要的 JSON 信息。

这是我在 Postman 响应面板中得到的信息, (如您所见,这是一种在 Colissimo 上生成法国邮政服务标签的方法)

我还可以补充一下,我尝试了很多 npm 包,但都没有成功。

如果您知道如何操作,非常感谢!

--uuid:f0bf15c8-03ba-41a4-8c9a-aac9d8e0d9ca
Content-Type: application/json;charset=UTF-8
Content-Transfer-Encoding: binary
Content-ID: <jsonInfos>

{"messages":[{"id":"0","type":"INFOS","messageContent":"La requête a été traitée avec succès","replacementValues":[]}],"labelXmlV2Reponse":null,"labelV2Response":{"parcelNumber":"8R42943164203","parcelNumberPartner":null,"pdfUrl":null,"fields":null}}
--uuid:f0bf15c8-03ba-41a4-8c9a-aac9d8e0d9ca
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-ID: <label>

%PDF-1.4
%����
3 0 obj <</Filter/FlateDecode/Length 1567>>stream
x��X�n7��W�L��;�`��)��!��I)�@��Ts�����������]

.... and more

我在路由中的简单 AXIOS 请求

let url = "https://ws.colissimo.fr/sls-ws/SlsServiceWSRest/2.0/generateLabel";

const response = await axios({
        url,
        method: 'POST',
        data,
        responseType: "stream"
      });
      console.log("data", response.data);

【问题讨论】:

  • 大多数人会去找一个可以为你解析多部分混合的库,因为你自己做有点麻烦。有关一些想法,请参阅stackoverflow.com/questions/38221104/…
  • 嘿@jfriend00 当然我看到了这篇文章并尝试了每个 npm 包,但没有一个与我试图解析的响应一起工作......:/
  • 那么,我认为您需要详细了解当您尝试应该能够处理这种格式的包时究竟是什么不起作用。要么你没有使用正确的包,这个特定的响应有某种问题,要么某处的某些代码中存在错误,因为有许多包应该能够处理multipart/mixed。所以,我们真的没有任何关于为什么他们都不为你工作的原因。您显示的代码未显示使用任何用于解析 multipart/mixed 的包。

标签: node.js express axios multipart


【解决方案1】:

您向 Colissimo Web 服务请求标签时遇到了同样的问题。 贝娄,我在测试时找到的解决方案:

function streamToString (stream) {
    const chunks = [];
    return new Promise((resolve, reject) => {
        stream.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
        stream.on('error', (err) => reject(err));
        stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
    })
}

axios.post(urlApiRest, generateLabelData, {responseType: 'stream'}).then(res => {
    res.data.pipe(fs.createWriteStream('../public/test.pdf')); // write label to pdf
    streamToString(res.data).then(strData => {
        const jsonInfo = extractInfoFromColissimoResponse(res, strData);
        console.log(jsonInfo.labelV2Response.parcelNumber); // retrieve parcel number
    });
}).catch(err => {
    console.log(err);
});

function extractInfoFromColissimoResponse(res, data) {
    let header = res.headers['content-type'];
    let boundary = header.split(' ')[1];
    boundary = boundary.split('=')[1];
    boundary = boundary.split('"')[1];
    
    const infoPart = data.split('--' + boundary)[1];
    const txtInfo = infoPart.split('<jsonInfos>')[1];

    return JSON.parse(txtInfo);
}

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
  • 这方面有进展吗?
  • 它仍然有效我很惊讶。只需要在axios调用中设置header到Content-type:application/json
猜你喜欢
  • 2021-09-30
  • 1970-01-01
  • 2016-11-08
  • 2011-04-11
  • 1970-01-01
  • 2010-10-25
  • 2013-05-28
  • 2015-12-03
相关资源
最近更新 更多