javascript node.js axios 下载文件并写入文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/55374755/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 10:32:14  来源:igfitidea点击:

node.js axios download file and writeFile

javascriptnode.jsaxios

提问by ar099968

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

我想下载一个 pdf 文件axios并保存在磁盘(服务器端)上fs.writeFile,我尝试过:

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!');
    });
});

the file is saved but the content is broken...

文件已保存,但内容已损坏...

how do I correctly save the file?

如何正确保存文件?

回答by ponury-kostek

You can simply use response.data.pipeand fs.createWriteStreamto pipe response to file

您可以简单地使用response.data.pipefs.createWriteStream管道响应文件

axios({
    method: "get",
    url: "https://xxx/my.pdf",
    responseType: "stream"
}).then(function (response) {
    response.data.pipe(fs.createWriteStream("/temp/my.pdf"));
});

回答by Armand

// 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);  
});  

回答by csotiriou

Actually, I believe the accepted answer has some flaws, as it will not handle the writestream properly, so if you call "then()" after Axios has given you the response, you will end up having a partially downloaded file.

实际上,我认为接受的答案有一些缺陷,因为它无法正确处理写入流,因此如果在 Axios 给您响应后调用“then()”,您最终将获得部分下载的文件。

This is a more appropriate solution when downloading slightly larger files:

当下载稍大的文件时,这是一个更合适的解决方案:

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

This way, you can call downloadFile(), call then()on the returned promise, and making sure that the downloaded file will have completed processing.

这样,您可以调用downloadFile(),调用then()返回的承诺,并确保下载的文件已完成处理。

回答by FedeSc

node fileSystem writeFileencodes data by default to UTF8. which could be a problem in your case.

节点文件系统writeFile默认将数据编码为 UTF8。在你的情况下这可能是一个问题。

Try setting your encoding to nulland skip encoding the received data:

尝试将您的编码设置为null并跳过对接收​​到的数据进行编码:

fs.writeFile('/temp/my.pdf', response.data, {encoding: null}, (err) => {...}

you can also decalre encoding as a string (instead of options object) if you only declare encoding and no other options. string will be handled as encoding value. as such:

如果您只声明编码而没有其他选项,您也可以将编码作为字符串(而不是选项对象)进行声明。字符串将作为编码值处理。像这样:

fs.writeFile('/temp/my.pdf', response.data, 'null', (err) => {...}

more read in fileSystem API write_file

更多阅读文件系统 API write_file

回答by levy9527

I have tried, and I'm sure that using response.data.pipeand fs.createWriteStreamcan work.

我已经试过了,我确信使用response.data.pipefs.createWriteStream可以工作。



Besides, I want to add my situation and solution

此外,我想补充一下我的情况和解决方案

Situation:

情况:

  • using koato develop a node.js server
  • using axiosto get a pdf via url
  • using pdf-parseto parse the pdf
  • extract some information of pdf and return it as json to browser
  • 利用koa开发的node.js服务器
  • 使用axios获得通过URL PDF文件
  • 使用pdf-parse解析PDF
  • 提取pdf的一些信息并将其作为json返回给浏览器

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.

在这个解决方案中,不需要写文件和读文件,效率更高。

回答by Khoa Tran dang

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

这是我使用 node js 运行的示例代码有一个同步错误

should be writeFilenot WriteFile

应该是writeFile而不是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