node.js axios download file stream and writeFile

前端 未结 8 964
花落未央
花落未央 2020-12-24 08:50

i want download a pdf file with axios and save on disk (server side) with fs.writeFile, i have tried:

axios.get(\'https://xxx/my.pd         


        
相关标签:
8条回答
  • 2020-12-24 09:11

    This is my example code run with node js There is a synctax error

    should be writeFile not WriteFile

    const axios = require('axios');
    const fs = require('fs');
    axios.get('http://www.africau.edu/images/default/sample.pdf', {responseType: 'blob'}).then(response => {
      fs.writeFile('./my.pdf', response.data, (err) => {
            if (err) throw err;
            console.log('The file has been saved!');
        });
    });
    
    

    After the file is saved it might look like in a text editor, but the file was saved properly

    %PDF-1.3
    %����
    
    1 0 obj
    <<
    /Type /Catalog
    /Outlines 2 0 R
    /Pages 3 0 R
    >>
    endobj
    
    2 0 obj
    <<
    /Type /Outlines
    /Count 0
    >>
    endobj
    
    3 0 obj
    <<
    /Type /Pages
    /Count 2
    /Kids [ 4 0 R 6 0 R ] 
    >>
    endobj
    
    0 讨论(0)
  • 2020-12-24 09:12

    You can simply use response.data.pipe and fs.createWriteStream to pipe response to file

    axios({
        method: "get",
        url: "https://xxx/my.pdf",
        responseType: "stream"
    }).then(function (response) {
        response.data.pipe(fs.createWriteStream("/temp/my.pdf"));
    });
    
    0 讨论(0)
  • 2020-12-24 09:17
    import download from "downloadjs";
    
    export const downloadFile = async (fileName) => {
        axios({
            method: "get",
            url: `/api/v1/users/resume/${fileName}`,
            responseType: "blob",
        }).then(function (response) {
            download(response.data, fileName);
        });
    };
    

    it's work fine to me

    0 讨论(0)
  • 2020-12-24 09:22

    I have tried, and I'm sure that using response.data.pipe and fs.createWriteStream can work.


    Besides, I want to add my situation and solution

    Situation:

    • using koa to develop a node.js server
    • using axios to get a pdf via url
    • using pdf-parse to parse the pdf
    • extract some information of pdf and return it as json to browser

    Solution:

    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),
            }
    })
    

    In this solution, it doesn't need to write file and read file, it's more efficient.

    0 讨论(0)
  • 2020-12-24 09:26
    // This works perfectly well! 
    const axios = require('axios'); 
    
    axios.get('http://www.sclance.com/pngs/png-file-download/png_file_download_1057991.png', {responseType: "stream"} )  
    .then(response => {  
    // Saving file to working directory  
        response.data.pipe(fs.createWriteStream("todays_picture.png"));  
    })  
        .catch(error => {  
        console.log(error);  
    });  
    
    0 讨论(0)
  • 2020-12-24 09:30

    The problem with broken file is because of backpressuring in node streams. You may find this link useful to read: https://nodejs.org/es/docs/guides/backpressuring-in-streams/

    I'm not really a fan of using Promise base declarative objects in JS codes as I feel it pollutes the actual core logic & makes the code hard to read. On top of it, you have to provision event handlers & listeners to make sure the code is completed.

    A more cleaner approach on the same logic which the accepted answer proposes is given below. It uses the concepts of stream pipelines.

    const util = require("util");
    const stream = require("stream");
    const pipeline = util.promisify(stream.pipeline);
    
    const downloadFile = async () => {
        try {
            await pipeline( axios.get('https://xxx/my.pdf', {responseType: 'blob'}), 
                                fs.createWriteStream("/temp/my.pdf"));
            console.log("donwload pdf pipeline successfull");   
        } catch (error) {
            console.error("donwload pdf pipeline failed", error);
        }
    }
    
    exports.downloadFile = downloadFile
    

    I hope you find this useful.

    0 讨论(0)
提交回复
热议问题