programing

(서드파티 라이브러리를 사용하지 않고) Node.js로 파일을 다운로드하는 방법

goodjava 2022. 10. 31. 21:15

(서드파티 라이브러리를 사용하지 않고) Node.js로 파일을 다운로드하는 방법

서드파티 라이브러리를 사용하지 않고 Node.js로 파일을 다운로드하려면 어떻게 해야 합니까?

특별히 필요한 건 없어요.지정된 URL에서 파일을 다운로드한 다음 지정된 디렉토리에 저장합니다.

HTTP 를 할 수 .GET하여 로 부르다response" " " 기능한한능한한 。

const http = require('http'); // or 'https' for https:// URLs
const fs = require('fs');

const file = fs.createWriteStream("file.jpg");
const request = http.get("http://i3.ytimg.com/vi/J---aiyznGQ/mqdefault.jpg", function(response) {
   response.pipe(file);

   // after download completed close filestream
   file.on("finish", () => {
       file.close();
       console.log("Download Completed");
   });
});

명령줄에서 대상 파일, 디렉토리 또는 URL 지정과 같은 정보 수집을 지원하려면 Commander와 같은 항목을 확인하십시오.

자세한 것은, https://sebhastian.com/nodejs-download-file/ 를 참조해 주세요.

실수를 처리하는 것을 잊지 마세요!다음 코드는 아우구스토 로만의 대답에 기초하고 있다.

var http = require('http');
var fs = require('fs');

var download = function(url, dest, cb) {
  var file = fs.createWriteStream(dest);
  var request = http.get(url, function(response) {
    response.pipe(file);
    file.on('finish', function() {
      file.close(cb);  // close() is async, call cb after close completes.
    });
  }).on('error', function(err) { // Handle errors
    fs.unlink(dest); // Delete the file async. (But we don't check the result)
    if (cb) cb(err.message);
  });
};

Michelle Tilley가 말했듯이 적절한 제어 흐름과 함께:

var http = require('http');
var fs = require('fs');

var download = function(url, dest, cb) {
  var file = fs.createWriteStream(dest);
  http.get(url, function(response) {
    response.pipe(file);
    file.on('finish', function() {
      file.close(cb);
    });
  });
}

finish이벤트, naigive 스크립트는 불완전한 파일로 끝날 수 있습니다.

편집: @Augusto Roman 님의 지적에 감사드립니다.cbfile.close 않는다).

에러 처리라고 하면, 리퀘스트 에러도 듣는 것이 좋습니다.응답 코드를 확인해서도 확인할 수 있습니다.여기서는 200개의 응답 코드에 대해서만 성공으로 간주되지만, 다른 코드가 좋을 수 있습니다.

const fs = require('fs');
const http = require('http');

const download = (url, dest, cb) => {
    const file = fs.createWriteStream(dest);

    const request = http.get(url, (response) => {
        // check if response is success
        if (response.statusCode !== 200) {
            return cb('Response status was ' + response.statusCode);
        }

        response.pipe(file);
    });

    // close() is async, call cb after close completes
    file.on('finish', () => file.close(cb));

    // check for request error too
    request.on('error', (err) => {
        fs.unlink(dest, () => cb(err.message)); // delete the (partial) file and then return the error
    });

    file.on('error', (err) => { // Handle errors
        fs.unlink(dest, () => cb(err.message)); // delete the (partial) file and then return the error
    });
};

이 코드의 비교적 단순함에도 불구하고 요청 모듈은 기본적으로 지원되지 않는 많은 프로토콜(hello HTTPS!)을 처리하기 때문에 사용하는 것이 좋습니다.http.

다음과 같이 처리됩니다.

const fs = require('fs');
const request = require('request');

const download = (url, dest, cb) => {
    const file = fs.createWriteStream(dest);
    const sendReq = request.get(url);
    
    // verify response code
    sendReq.on('response', (response) => {
        if (response.statusCode !== 200) {
            return cb('Response status was ' + response.statusCode);
        }

        sendReq.pipe(file);
    });

    // close() is async, call cb after close completes
    file.on('finish', () => file.close(cb));

    // check for request errors
    sendReq.on('error', (err) => {
        fs.unlink(dest, () => cb(err.message)); // delete the (partial) file and then return the error
    });

    file.on('error', (err) => { // Handle errors
        fs.unlink(dest, () => cb(err.message)); // delete the (partial) file and then return the error
    });
};

편집:

하도록 하기 위해서https, 변경

const http = require('http');

로.

const http = require('https');

과 gfxmonk의 .file.close()완료하고 있습니다. file.close()는 실제로 클로즈가 완료되면 호출된 콜백을 받습니다.그렇지 않으면 파일을 즉시 사용하지 못할 수 있습니다(매우 드물게!).

완전한 솔루션은 다음과 같습니다.

var http = require('http');
var fs = require('fs');

var download = function(url, dest, cb) {
  var file = fs.createWriteStream(dest);
  var request = http.get(url, function(response) {
    response.pipe(file);
    file.on('finish', function() {
      file.close(cb);  // close() is async, call cb after close completes.
    });
  });
}

종료 이벤트를 기다리지 않으면 Naigive 스크립트는 불완전한 파일로 끝날 수 있습니다. 하지 않고, 스케줄 하지 않고,cbclose는 와 실제로 수 .callback by close, "callback"은 "close"로 표시됩니다.

node.js가 변경되었을 가능성이 있습니다만, 다른 솔루션(노드 v8.1.2 사용)에 몇 가지 문제가 있는 것 같습니다.

  1. file.close() finish로는 「」입니다. 디폴트에 따라fs.createWriteStreamautoClose로 설정됩니다.https://nodejs.org/api/fs.html#fs_fs_createwritestream_path_options
  2. file.close()에러시에 호출됩니다.는 이 기능이 하지 않을 수 .unlink()). 단, 통상은 https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options 입니다.
  3. .statusCode !== 200
  4. fs.unlink()콜백이 없는 경우는 권장되지 않습니다(경고).
  5. ifdest이 존재합니다 파일은 덮어쓰기 됩니다.

다음은 이러한 문제를 처리하는 수정된 솔루션(ES6 및 약속 사용)입니다.

const http = require("http");
const fs = require("fs");

function download(url, dest) {
    return new Promise((resolve, reject) => {
        const file = fs.createWriteStream(dest, { flags: "wx" });

        const request = http.get(url, response => {
            if (response.statusCode === 200) {
                response.pipe(file);
            } else {
                file.close();
                fs.unlink(dest, () => {}); // Delete temp file
                reject(`Server responded with ${response.statusCode}: ${response.statusMessage}`);
            }
        });

        request.on("error", err => {
            file.close();
            fs.unlink(dest, () => {}); // Delete temp file
            reject(err.message);
        });

        file.on("finish", () => {
            resolve();
        });

        file.on("error", err => {
            file.close();

            if (err.code === "EEXIST") {
                reject("File already exists");
            } else {
                fs.unlink(dest, () => {}); // Delete temp file
                reject(err.message);
            }
        });
    });
}

es6 스타일의 공약을 찾아오신 분들께는 이런 느낌일 것 같아요.

var http = require('http');
var fs = require('fs');

function pDownload(url, dest){
  var file = fs.createWriteStream(dest);
  return new Promise((resolve, reject) => {
    var responseSent = false; // flag to make sure that response is sent only once.
    http.get(url, response => {
      response.pipe(file);
      file.on('finish', () =>{
        file.close(() => {
          if(responseSent)  return;
          responseSent = true;
          resolve();
        });
      });
    }).on('error', err => {
        if(responseSent)  return;
        responseSent = true;
        reject(err);
    });
  });
}

//example
pDownload(url, fileLocation)
  .then( ()=> console.log('downloaded file no issues...'))
  .catch( e => console.error('error while downloading', e));

위의 다른 답변과 몇 가지 미묘한 문제에 기초하여, 저의 시도는 다음과 같습니다.

  1. 에 파일이 하지 않는지 합니다.fs.access.
  2. '만들다'만.fs.createWriteStream'A가 200 OK 이, ,, of의 양이 .fs.unlink임시 파일 핸들을 정리하는 데 필요한 명령입니다.
  3. Even on a 심지어200 OK we can still possibly 우리는 여전히 할 수 있다.reject due to an 의 이유로EEXIST파일이 이미 존재합니다. 네트워크 통화를 하는 동안 파일이 이미 있습니다.파일이 이미 존재합니다(네트워크 콜 실행 중에 다른 프로세스가 파일을 생성하지 않은 경우).
  4. Recursively call 재귀 호출download if you get a 만약 네가 A를 얻으면301 Moved Permanently or 또는302 Found (Moved Temporarily)헤더에 제공된 링크 위치를 리디렉션합니다.헤더에 지정된 링크 위치에 따라 리다이렉트합니다.
  5. 다른 답변 중 일부는 른 답 응 부 복 출 제 되 는 the issue문 answers recurs of호반로ively일 with the other중 some다으적 calling가 the issue answers of recursdownload was that they called 그들이 전화했다는 것이다.resolve(download)대 대신에download(...).then(() => resolve()) so the 그래서 그Promise다운로드가 실제로 완료되기 전에 반환됩니다.다운로드가 실제로 끝나기 전에 돌아갑니다.이렇게 하면 약속의 중첩된 사슬이 올바른 순서로 해결됩니다.
  6. temp 파일을 비동기적으로 정리하는 것은 멋진 이지만, 저는 이 약속이 해결되거나 거부되면 모든 작업이 완료된다는 것을 알기 위해 그 작업이 완료된 후에만 거부하기로 했습니다.
const https = require('https');
const fs = require('fs');

/**
 * Download a resource from `url` to `dest`.
 * @param {string} url - Valid URL to attempt download of resource
 * @param {string} dest - Valid path to save the file.
 * @returns {Promise<void>} - Returns asynchronously when successfully completed download
 */
function download(url, dest) {
  return new Promise((resolve, reject) => {
    // Check file does not exist yet before hitting network
    fs.access(dest, fs.constants.F_OK, (err) => {

        if (err === null) reject('File already exists');

        const request = https.get(url, response => {
            if (response.statusCode === 200) {
       
              const file = fs.createWriteStream(dest, { flags: 'wx' });
              file.on('finish', () => resolve());
              file.on('error', err => {
                file.close();
                if (err.code === 'EEXIST') reject('File already exists');
                else fs.unlink(dest, () => reject(err.message)); // Delete temp file
              });
              response.pipe(file);
            } else if (response.statusCode === 302 || response.statusCode === 301) {
              //Recursively follow redirects, only a 200 will resolve.
              download(response.headers.location, dest).then(() => resolve());
            } else {
              reject(`Server responded with ${response.statusCode}: ${response.statusMessage}`);
            }
          });
      
          request.on('error', err => {
            reject(err.message);
          });
    });
  });
}

시간 초과가 있는 솔루션, 메모리 누수 방지:

다음 코드는 Brandon Tilley의 답변을 기반으로 합니다.

var http = require('http'),
    fs = require('fs');

var request = http.get("http://example12345.com/yourfile.html", function(response) {
    if (response.statusCode === 200) {
        var file = fs.createWriteStream("copy.html");
        response.pipe(file);
    }
    // Add timeout.
    request.setTimeout(12000, function () {
        request.abort();
    });
});

오류가 발생했을 때 파일을 만들지 말고 X초 후에 타임아웃을 사용하여 요청을 닫는 것이 좋습니다.

안녕하세요. child_process module과 curl 명령어를 사용할 수 있을 것 같습니다.

const cp = require('child_process');

let download = async function(uri, filename){
    let command = `curl -o ${filename}  '${uri}'`;
    let result = cp.execSync(command);
};


async function test() {
    await download('http://zhangwenning.top/20181221001417.png', './20181221001417.png')
}

test()

또한 대용량 여러 파일을 다운로드하는 경우 클러스터 모듈을 사용하여 더 많은 CPU 코어를 사용할 수 있습니다.

최신 버전(ES6, Promise, Node 12.x+)은 http에서 동작합니다.ALso는 리다이렉트 302 및 301을 지원합니다.서드파티 라이브러리는 표준 Node.js libs로 쉽게 사용할 수 있기 때문에 사용하지 않기로 했습니다.

// download.js
import fs from 'fs'
import https from 'https'
import http from 'http'
import { basename } from 'path'
import { URL } from 'url'

const TIMEOUT = 10000

function download (url, dest) {
  const uri = new URL(url)
  if (!dest) {
    dest = basename(uri.pathname)
  }
  const pkg = url.toLowerCase().startsWith('https:') ? https : http

  return new Promise((resolve, reject) => {
    const request = pkg.get(uri.href).on('response', (res) => {
      if (res.statusCode === 200) {
        const file = fs.createWriteStream(dest, { flags: 'wx' })
        res
          .on('end', () => {
            file.end()
            // console.log(`${uri.pathname} downloaded to: ${path}`)
            resolve()
          })
          .on('error', (err) => {
            file.destroy()
            fs.unlink(dest, () => reject(err))
          }).pipe(file)
      } else if (res.statusCode === 302 || res.statusCode === 301) {
        // Recursively follow redirects, only a 200 will resolve.
        download(res.headers.location, dest).then(() => resolve())
      } else {
        reject(new Error(`Download request failed, response status: ${res.statusCode} ${res.statusMessage}`))
      }
    })
    request.setTimeout(TIMEOUT, function () {
      request.abort()
      reject(new Error(`Request timeout after ${TIMEOUT / 1000.0}s`))
    })
  })
}

export default download

가 수정한 그의 요지를 위해 안드레이 트카첸코에게 쿠도

다른 파일에 포함시켜 사용하다

const download = require('./download.js')
const url = 'https://raw.githubusercontent.com/replace-this-with-your-remote-file'
console.log('Downloading ' + url)

async function run() {
  console.log('Downloading file')
  try {
    await download(url, 'server')
    console.log('Download done')
  } catch (e) {
    console.log('Download failed')
    console.log(e.message)
  }
}

run()

Vince Yuan의 코드는 훌륭하지만 뭔가 잘못된 것 같다.

function download(url, dest, callback) {
    var file = fs.createWriteStream(dest);
    var request = http.get(url, function (response) {
        response.pipe(file);
        file.on('finish', function () {
            file.close(callback); // close() is async, call callback after close completes.
        });
        file.on('error', function (err) {
            fs.unlink(dest); // Delete the file async. (But we don't check the result)
            if (callback)
                callback(err.message);
        });
    });
}
const download = (url, path) => new Promise((resolve, reject) => {
http.get(url, response => {
    const statusCode = response.statusCode;

    if (statusCode !== 200) {
        return reject('Download error!');
    }

    const writeStream = fs.createWriteStream(path);
    response.pipe(writeStream);

    writeStream.on('error', () => reject('Error writing to file!'));
    writeStream.on('finish', () => writeStream.close(resolve));
});}).catch(err => console.error(err));

http와 https를 모두 사용할 수 있기 때문에 request()를 선호합니다.

request('http://i3.ytimg.com/vi/J---aiyznGQ/mqdefault.jpg')
  .pipe(fs.createWriteStream('cat.jpg'))

✅파이프라인을 사용하면 다른 스트림이 모두 닫혀 메모리 누수가 발생하지 않습니다.

작업 예:

const http = require('http');
const { pipeline } = require('stream');
const fs = require('fs');

const file = fs.createWriteStream('./file.jpg');

http.get('http://via.placeholder.com/150/92c952', response => {
  pipeline(
    response,
    file,
    err => {
      if (err)
        console.error('Pipeline failed.', err);
      else
        console.log('Pipeline succeeded.');
    }
  );
});

답변부터 "스트림에서 .pipe와 .pipeline의 차이점은 무엇입니까?"까지입니다.

http2 모듈 사용

http, https request 모듈을 사용하여 답변을 확인했습니다.다른 네이티브 노드를 사용하여 추가하려고 합니다.http 또는 https 프로토콜을 지원하는 JS 모듈:

솔루션

공식 노드를 참조했습니다.JS API뿐만 아니라 이 질문에 대한 다른 답변도 있습니다.시험 삼아 써본 테스트는 다음과 같습니다.

import * as fs from 'fs';
import * as _path from 'path';
import * as http2 from 'http2';

/* ... */

async function download( host, query, destination )
{
    return new Promise
    (
        ( resolve, reject ) =>
        {
            // Connect to client:
            const client = http2.connect( host );
            client.on( 'error', error => reject( error ) );

            // Prepare a write stream:
            const fullPath = _path.join( fs.realPathSync( '.' ), destination );
            const file = fs.createWriteStream( fullPath, { flags: "wx" } );
            file.on( 'error', error => reject( error ) );

            // Create a request:
            const request = client.request( { [':path']: query } );

            // On initial response handle non-success (!== 200) status error:
            request.on
            (
                'response',
                ( headers/*, flags*/ ) =>
                {
                    if( headers[':status'] !== 200 )
                    {
                        file.close();
                        fs.unlink( fullPath, () => {} );
                        reject( new Error( `Server responded with ${headers[':status']}` ) );
                    }
                }
            );

            // Set encoding for the payload:
            request.setEncoding( 'utf8' );

            // Write the payload to file:
            request.on( 'data', chunk => file.write( chunk ) );

            // Handle ending the request
            request.on
            (
                'end',
                () =>
                {
                    file.close();
                    client.close();
                    resolve( { result: true } );
                }
            );

            /* 
                You can use request.setTimeout( 12000, () => {} ) for aborting
                after period of inactivity
            */

            // Fire off [flush] the request:
            request.end();
        }
    );
}

다음으로 예를 제시하겠습니다.

/* ... */

let downloaded = await download( 'https://gitlab.com', '/api/v4/...', 'tmp/tmpFile' );

if( downloaded.result )
{
    // Success!
}

// ...

외부 참조

정보 편집

  • 솔루션은 typescript, 함수는 클래스 메서드에 대해 작성되었습니다.그러나 이를 언급하지 않았다면 javascript를 올바르게 사용하지 않았다면 이 솔루션은 javascript 추정 사용자에게 작동하지 않았을 것입니다.function우리의 기고자가 즉시 추가한 선언문입니다.★★★★★★★★★★★★★★★★★★!

https://github.com/douzi8/ajax-request#download 를 사용할 수 있습니다.

request.download('http://res.m.ctrip.com/html5/Content/images/57.png', 
  function(err, res, body) {}
);

Promise를 사용하여 다운로드하여 판독 가능한 스트림을 해결합니다.리다이렉트를 처리하기 위해 추가 논리를 사용합니다.

var http = require('http');
var promise = require('bluebird');
var url = require('url');
var fs = require('fs');
var assert = require('assert');

function download(option) {
    assert(option);
    if (typeof option == 'string') {
        option = url.parse(option);
    }

    return new promise(function(resolve, reject) {
        var req = http.request(option, function(res) {
            if (res.statusCode == 200) {
                resolve(res);
            } else {
                if (res.statusCode === 301 && res.headers.location) {
                    resolve(download(res.headers.location));
                } else {
                    reject(res.statusCode);
                }
            }
        })
        .on('error', function(e) {
            reject(e);
        })
        .end();
    });
}

download('http://localhost:8080/redirect')
.then(function(stream) {
    try {

        var writeStream = fs.createWriteStream('holyhigh.jpg');
        stream.pipe(writeStream);

    } catch(e) {
        console.error(e);
    }
});

download.download(예: /project/downloads/downloads.downloads)

const fs = require('fs');
const request = require('request');

const download = (uri, filename, callback) => {
    request.head(uri, (err, res, body) => {
        console.log('content-type:', res.headers['content-type']);
        console.log('content-length:', res.headers['content-length']);

        request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
    });
};

module.exports = { download };


app.module

... 
// part of imports
const { download } = require('./utils/download');

...
// add this function wherever
download('https://imageurl.com', 'imagename.jpg', () => {
  console.log('done')
});

express를 사용하는 경우 res.download() 메서드를 사용합니다.그렇지 않으면 fs 모듈을 사용합니다.

app.get('/read-android', function(req, res) {
   var file = "/home/sony/Documents/docs/Android.apk";
    res.download(file) 
}); 

(또는)

   function readApp(req,res) {
      var file = req.fileName,
          filePath = "/home/sony/Documents/docs/";
      fs.exists(filePath, function(exists){
          if (exists) {     
            res.writeHead(200, {
              "Content-Type": "application/octet-stream",
              "Content-Disposition" : "attachment; filename=" + file});
            fs.createReadStream(filePath + file).pipe(res);
          } else {
            res.writeHead(400, {"Content-Type": "text/plain"});
            res.end("ERROR File does NOT Exists.ipa");
          }
        });  
    }

경로 : img type : jpg random uniqid

    function resim(url) {

    var http = require("http");
    var fs = require("fs");
    var sayi = Math.floor(Math.random()*10000000000);
    var uzanti = ".jpg";
    var file = fs.createWriteStream("img/"+sayi+uzanti);
    var request = http.get(url, function(response) {
  response.pipe(file);
});

        return sayi+uzanti;
}

도서관이 없다면 그것은 단지 지적하기에 버그가 될 수 있다.다음은 몇 가지 예입니다.

  • http 리다이렉션을 처리할 수 없습니다.이 URL은 바이너리입니다.https://calibre-ebook.com/dist/portable 입니다.
  • 을 사용할 수 "Https URL" 이 됩니다.Protocol "https:" not supported.

제 제안은 다음과 같습니다.

  • wget ★★★★★★★★★★★★★★★★★」curl
  • node-wget-module과 같은 도구를 사용합니다.이 도구도 매우 사용하기 쉽습니다. var wget = require('node-wget-promise'); wget('http://nodejs.org/images/logo.svg');

기존 솔루션이 제 요구 사항에 맞지 않았기 때문에 저만의 솔루션을 작성했습니다.

대상:

  • 를 HTTPS로 )httpHTTP の 운 http http )
  • 약속 기반 기능
  • 전송 경로 처리(상태 302)
  • 브라우저 헤더 - 일부 CDN에 필요
  • URL로부터의 파일명(하드코드화도 가능)
  • 에러 처리

No TS하고 있는 자유롭게 타입을 드롭 하거나, JS(No Flow, TS)주세요..d.ts

index.displaces를 표시합니다.

import httpsDownload from httpsDownload;
httpsDownload('https://example.com/file.zip', './');

https 다운로드[ts|ts]

import https from "https";
import fs from "fs";
import path from "path";

function download(
  url: string,
  folder?: string,
  filename?: string
): Promise<void> {
  return new Promise((resolve, reject) => {
    const req = https
      .request(url, { headers: { "User-Agent": "javascript" } }, (response) => {
        if (response.statusCode === 302 && response.headers.location != null) {
          download(
            buildNextUrl(url, response.headers.location),
            folder,
            filename
          )
            .then(resolve)
            .catch(reject);
          return;
        }

        const file = fs.createWriteStream(
          buildDestinationPath(url, folder, filename)
        );
        response.pipe(file);
        file.on("finish", () => {
          file.close();
          resolve();
        });
      })
      .on("error", reject);
    req.end();
  });
}

function buildNextUrl(current: string, next: string) {
  const isNextUrlAbsolute = RegExp("^(?:[a-z]+:)?//").test(next);
  if (isNextUrlAbsolute) {
    return next;
  } else {
    const currentURL = new URL(current);
    const fullHost = `${currentURL.protocol}//${currentURL.hostname}${
      currentURL.port ? ":" + currentURL.port : ""
    }`;
    return `${fullHost}${next}`;
  }
}

function buildDestinationPath(url: string, folder?: string, filename?: string) {
  return path.join(folder ?? "./", filename ?? generateFilenameFromPath(url));
}

function generateFilenameFromPath(url: string): string {
  const urlParts = url.split("/");
  return urlParts[urlParts.length - 1] ?? "";
}

export default download;
function download(url, dest, cb) {

  var request = http.get(url, function (response) {

    const settings = {
      flags: 'w',
      encoding: 'utf8',
      fd: null,
      mode: 0o666,
      autoClose: true
    };

    // response.pipe(fs.createWriteStream(dest, settings));
    var file = fs.createWriteStream(dest, settings);
    response.pipe(file);

    file.on('finish', function () {
      let okMsg = {
        text: `File downloaded successfully`
      }
      cb(okMsg);
      file.end(); 
    });
  }).on('error', function (err) { // Handle errors
    fs.unlink(dest); // Delete the file async. (But we don't check the result)
    let errorMsg = {
      text: `Error in file downloadin: ${err.message}`
    }
    if (cb) cb(errorMsg);
  });
};
var fs = require('fs'),
    request = require('request');

var download = function(uri, filename, callback){
    request.head(uri, function(err, res, body){
    console.log('content-type:', res.headers['content-type']);
    console.log('content-length:', res.headers['content-length']);
    request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);

    }); 
};   

download('https://www.cryptocompare.com/media/19684/doge.png', 'icons/taskks12.png', function(){
    console.log('done');
});

서드파티에 의존하지 않고 리다이렉트를 검색하는 또 다른 방법은 다음과 같습니다.

        var download = function(url, dest, cb) {
            var file = fs.createWriteStream(dest);
            https.get(url, function(response) {
                if ([301,302].indexOf(response.statusCode) !== -1) {
                    body = [];
                    download(response.headers.location, dest, cb);
                  }
              response.pipe(file);
              file.on('finish', function() {
                file.close(cb);  // close() is async, call cb after close completes.
              });
            });
          }

도 한번 .res.redirectURL로 하여 파일https URL을 합니다.

예를 들어 다음과 같습니다.res.redirect('https//static.file.com/file.txt');

특히 pdfs나 랜덤한 다른 파일에 대해서는 이 방법이 가장 도움이 됩니다.

import fs from "fs";

  fs.appendFile("output_file_name.ext", fileDataInBytes, (err) => {
    if (err) throw err;
    console.log("File saved!");
  });

하시길 권합니다.res.download음음음같 뭇매하다

app.get('/download', function(req, res){
  const file = `${__dirname}/folder/abc.csv`;
  res.download(file); // Set disposition and send it.
});
var requestModule=require("request");

requestModule(filePath).pipe(fs.createWriteStream('abc.zip'));

언급URL : https://stackoverflow.com/questions/11944932/how-to-download-a-file-with-node-js-without-using-third-party-libraries