복붙노트

[NODEJS] 어떻게 (타사 라이브러리를 사용하지 않고) Node.js를 가진 파일을 다운로드?

NODEJS

어떻게 (타사 라이브러리를 사용하지 않고) Node.js를 가진 파일을 다운로드?

해결법


  1. 1.당신은 쓰기 가능한 파일 스트림로의 HTTP GET 요청 및 파이프의 응답을 생성 할 수 있습니다 :

    당신은 쓰기 가능한 파일 스트림로의 HTTP GET 요청 및 파이프의 응답을 생성 할 수 있습니다 :

    const http = require('http');
    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);
    });
    

    대상 파일이나 디렉토리 또는 URL을 지정처럼 - - 명령 줄에 대한 정보를 수집 지원하려면 사령관 같은 것을 확인하십시오.


  2. 2.핸들 오류를 잊지 마세요! 다음 코드는 아우 로마의 대답을 기반으로합니다.

    핸들 오류를 잊지 마세요! 다음 코드는 아우 로마의 대답을 기반으로합니다.

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

  3. 3.미셸 틸리는하지만, 적절한 제어 흐름 말했다 :

    미셸 틸리는하지만, 적절한 제어 흐름 말했다 :

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

    마무리 이벤트를 기다리지 않고, 순진 스크립트는 불완전한 파일을 끝낼 수 있습니다.

    편집 : 그 CB를 지적 @Augusto 로마 덕분에 file.close에 전달되어야하며, 명시 적으로 호출되지 않습니다.


  4. 4.오류를 처리 말하자면, 그것은 요청 오류에 대한 더 나은 듣기도합니다. 난 응답 코드를 확인하여 확인할 것입니다. 여기에 단지 200 응답 코드에 대한 성공 간주하지만, 다른 코드는 좋은 수 있습니다.

    오류를 처리 말하자면, 그것은 요청 오류에 대한 더 나은 듣기도합니다. 난 응답 코드를 확인하여 확인할 것입니다. 여기에 단지 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);
            return cb(err.message);
        });
    
        file.on('error', (err) => { // Handle errors
            fs.unlink(dest); // Delete the file async. (But we don't check the result) 
            return cb(err.message);
        });
    };
    

    그것은 더 많은 프로토콜을 처리로이 코드의 상대적 단순성에도 불구하고, 나는 (안녕하세요 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);
            return cb(err.message);
        });
    
        file.on('error', (err) => { // Handle errors
            fs.unlink(dest); // Delete the file async. (But we don't check the result)
            return cb(err.message);
        });
    };
    

  5. 5.gfxmonk의 대답은 콜백과 file.close () 완료 사이에 아주 꽉 데이터 경주가 있습니다. file.close () 실제로 닫기가 완료되면 호출되는 콜백을합니다. 그렇지 않으면, 파일의 즉각적인 용도는 (아주 드물게!) 실패 할 수 없습니다.

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

    마무리 이벤트를 기다리지 않고, 순진 스크립트는 불완전한 파일을 끝낼 수 있습니다. 가까운 통해 CB 콜백을 예약하지 않으면, 당신은 실제로 파일과 파일에 액세스 준비되는 사이에 레이스를받을 수 있습니다.


  6. 6.아마 Node.js를 변경,하지만 다른 솔루션 (노드 V8.1.2을 사용하여) 몇 가지 문제가있는 것 같습니다있다 :

    아마 Node.js를 변경,하지만 다른 솔루션 (노드 V8.1.2을 사용하여) 몇 가지 문제가있는 것 같습니다있다 :

    다음은 이러한 문제를 처리 (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);
                }
            });
        });
    }
    

  7. 7.다음 코드는 브랜든 틸리의 대답을 기반으로합니다 :

    다음 코드는 브랜든 틸리의 대답을 기반으로합니다 :

    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의 초 후에 요청을 닫 사용 시간 제한 선호하지 마십시오.


  8. 8.ES6 스타일의 약속을 기반으로 방법을 찾아 온 사람들을 위해, 나는 그것이 같은 것 같아요

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

  9. 9.빈스 위안의 코드는 훌륭하지만 뭔가 잘못된 것 같다.

    빈스 위안의 코드는 훌륭하지만 뭔가 잘못된 것 같다.

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

  10. 10.당신이 그것으로 HTTP와 HTTPS를 모두 사용할 수 있기 때문에 나는 () 요청을 선호합니다.

    당신이 그것으로 HTTP와 HTTPS를 모두 사용할 수 있기 때문에 나는 () 요청을 선호합니다.

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

  11. 11.

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

  12. 12.안녕, 난 당신이 child_process 모듈과 컬 명령을 사용할 수 있다고 생각합니다.

    안녕, 난 당신이 child_process 모듈과 컬 명령을 사용할 수 있다고 생각합니다.

    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 코어를 사용하는 클러스터 모듈을 사용할 수 있습니다.


  13. 13."스트림에 .pipe와 .pipeline의 차이는 무엇"에 대한 내 대답에서.

    "스트림에 .pipe와 .pipeline의 차이는 무엇"에 대한 내 대답에서.


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

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

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

  15. 15.약속, 결의 읽을 수있는 스트림을 사용하여 다운로드합니다. 리디렉션을 처리하기 위해 별도의 로직을 넣어.

    약속, 결의 읽을 수있는 스트림을 사용하여 다운로드합니다. 리디렉션을 처리하기 위해 별도의 로직을 넣어.

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

  16. 16.당신이 표현을 사용 res.download를 사용하는 경우 () 메소드. 그렇지 않으면 모듈 사용을 내지 fs.

    당신이 표현을 사용 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");
              }
            });  
        }
    

  17. 17.위의 다른 답변과 미묘한 문제를 바탕으로, 여기 내 시도이다.

    위의 다른 답변과 미묘한 문제를 바탕으로, 여기 내 시도이다.

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

  18. 18.경로 : IMG 유형 : JPG 임의 uniqid

    경로 : IMG 유형 : JPG 임의 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;
    }
    

  19. 19.download.js (즉 /project/utils/download.js)

    download.js (즉 /project/utils/download.js)

    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.js

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

  20. 20.이후 내 자신의 솔루션을 쓰기 내 요구 사항에 적합하지 않은 기존의.

    이후 내 자신의 솔루션을 쓰기 내 요구 사항에 적합하지 않은 기존의.

    이것이 커버 :

    그것은 그것의 안전 입력합니다. 당신이 .d.ts 파일에 일반 JS (어떤 흐름, 아니 TS) 또는 변환 작업하는 경우 유형을 드롭 주시기 바랍니다

    하는 index.js

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

    . httpsDownload [JS | 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;
    

  21. 21.라이브러리 없이는 지적 단지 버그가있을 수 있습니다. 여기 몇 가지 있습니다 :

    라이브러리 없이는 지적 단지 버그가있을 수 있습니다. 여기 몇 가지 있습니다 :

    내 제안 여기 :


  22. 22.

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

  23. 23.당신은 HTTPS 파일 다운로드 URL에 res.redirect를 사용하여 시도 할 수 있으며, 다음 파일을 다운로드 할 수 있습니다.

    당신은 HTTPS 파일 다운로드 URL에 res.redirect를 사용하여 시도 할 수 있으며, 다음 파일을 다운로드 할 수 있습니다.

    마찬가지로 : res.redirect ( 'HTTPS // static.file.com / file.txt를');


  24. 24.

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

  25. 25.여기 또 다른 방법은 제 3 자 의존성도 리디렉션에 대한 검색하지 않고 그것을 처리하기 위해 :

    여기 또 다른 방법은 제 3 자 의존성도 리디렉션에 대한 검색하지 않고 그것을 처리하기 위해 :

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

  26. 26.우리는 다운로드 노드 모듈과 매우 간단 사용할 수 있습니다, 아래를 참조하시기 바랍니다 https://www.npmjs.com/package/download

    우리는 다운로드 노드 모듈과 매우 간단 사용할 수 있습니다, 아래를 참조하시기 바랍니다 https://www.npmjs.com/package/download


  27. 27.

    var requestModule=require("request");
    
    requestModule(filePath).pipe(fs.createWriteStream('abc.zip'));
    
  28. from https://stackoverflow.com/questions/11944932/how-to-download-a-file-with-node-js-without-using-third-party-libraries by cc-by-sa and MIT license