je veux télécharger un fichier pdf avec axios
et enregistrer sur le disque (côté serveur) avec fs.writeFile
, j'ai essayé:
axios.get('https://xxx/my.pdf', {responseType: 'blob'}).then(response => {
fs.writeFile('/temp/my.pdf', response.data, (err) => {
if (err) throw err;
console.log('The file has been saved!');
});
});
le fichier est enregistré mais le contenu est cassé ...
comment enregistrer correctement le fichier?
J'ai essayé et je suis sûr que l'utilisation de response.data.pipe
et fs.createWriteStream
peut marcher.
De plus, je veux ajouter ma situation et ma solution
Situation:
koa
pour développer un serveur node.jsaxios
pour obtenir un pdf via urlpdf-parse
pour analyser le pdfSolution:
const Koa = require('koa');
const app = new Koa();
const axios = require('axios')
const fs = require("fs")
const pdf = require('pdf-parse');
const utils = require('./utils')
app.listen(process.env.PORT || 3000)
app.use(async (ctx, next) => {
let url = 'https://path/name.pdf'
let resp = await axios({
url: encodeURI(url),
responseType: 'arraybuffer'
})
let data = await pdf(resp.data)
ctx.body = {
phone: utils.getPhone(data.text),
email: utils.getEmail(data.text),
}
})
Dans cette solution, il n'a pas besoin d'écrire et de lire un fichier, c'est plus efficace.
En fait, je pense que la réponse acceptée a quelques défauts, car elle ne traitera pas correctement le flux écrit, donc si vous appelez "then ()" après qu'Axios vous ait donné la réponse, vous finirez par avoir un fichier partiellement téléchargé.
Il s'agit d'une solution plus appropriée lors du téléchargement de fichiers légèrement plus volumineux:
export async function downloadFile(fileUrl: string, outputLocationPath: string) {
const writer = createWriteStream(outputLocationPath);
return Axios({
method: 'get',
url: fileUrl,
responseType: 'stream',
}).then(response => {
//ensure that the user can call `then()` only when the file has
//been downloaded entirely.
return new Promise((resolve, reject) => {
response.data.pipe(writer);
let error = null;
writer.on('error', err => {
error = err;
writer.close();
reject(err);
});
writer.on('close', () => {
if (!error) {
resolve(true);
}
//no need to call the reject here, as it will have been called in the
//'error' stream;
});
});
});
}
De cette façon, vous pouvez appeler downloadFile()
, appeler then()
sur la promesse retournée et vous assurer que le fichier téléchargé aura terminé le traitement.