已经好几天了,我一直被困在一个我认为应该解决的简单问题上......
我有一个 NodeJS Express 应用程序,根据对特定路由的请求,它会向外部服务发出带有有效负载的 AXIOS post 请求。 该服务确实以多部分/混合内容类型进行响应(标题中提到了内容类型)。 响应包含一个 PDF 和一个包含信息的 JSON。
我成功地将response.data完全保存为PDF格式在AWS S3上。 但我无法找到至少一种方法来解析response.data以提取我需要的JSON信息。
这是我在邮递员回复面板中得到的内容, (正如您所注意到的,这是一种在 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);
我在向 Colissimo 网络服务请求标签时遇到了同样的问题。 下面是我在测试时发现的解决方案:
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);
}
我知道这是一个老问题,但我在使用相同的 API 时发现了它,并且我认为我的方法更加安全。
您可以使用nodemailer包中的简单解析器。您只需从响应中获取所有标头即可。例如:
const axios = require('axios');
const simpleParser = require('mailparser').simpleParser;
const {headers, data} = await axios.post(url, requestBody, { responseType: 'arraybuffer' });
const rawHeaders = Object.entries(result.headers)
.map(([key, value]) => `${key}: ${value}`)
.join('\r\n');
const content = Buffer.concat([Buffer.from(rawHeaders + '\r\n', 'ascii'), data]);
const parsed = await simpleParser(content);
const infoAttachment = parsed.attachments.find(
(attachment) => attachment.cid === 'jsonInfos',
);
const infos = JSON.parse(infoAttachment.content.toString());
const labelAttachment = parsed.attachments.find(
(attachment) => attachment.cid === 'label',
);