Jak pobrać plik z Node.js (bez korzystania z bibliotek innych firm)?

Jak pobrać plik z Node.js bez korzystania z bibliotek stron trzecich?

Nie potrzebuję niczego specjalnego. Chcę tylko pobrać plik z podanego adresu URL, a następnie zapisać go w danym katalogu.

Author: KARTHIKEYAN.A, 2012-08-14

19 answers

Możesz utworzyć żądanie HTTP GET i skierować je response do zapisywalnego strumienia plików:

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

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

Jeśli chcesz wspomóc zbieranie informacji w wierszu poleceń-na przykład określanie pliku docelowego, katalogu lub adresu URL-sprawdź coś w rodzaju Commander .

 399
Author: Michelle Tilley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-12 01:04:59

Nie zapomnij poradzić sobie z błędami! Poniższy Kodeks oparty jest na odpowiedzi Augusto Romana.

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);
  });
};
 430
Author: Vince Yuan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-07 08:24:11

Jak powiedział Brandon Tilley, ale z odpowiednim przepływem sterowania:

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

Bez czekania na zdarzenie finish, naiwne skrypty mogą skończyć z niekompletnym plikiem.

Edit: podziękowania dla @ Augusto Roman za zwrócenie uwagi, że cb powinno być przekazywane do file.close, a nie wywoływane wprost.

 118
Author: gfxmonk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-12 23:59:20

Mówiąc o obsłudze błędów, jeszcze lepiej jest słuchać błędów żądania. Sprawdzałem nawet Kod odpowiedzi. Tutaj jest uważany za sukces tylko dla kodu odpowiedzi 200, ale inne kody mogą być dobre.

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

var download = function(url, dest, cb) {
    var file = fs.createWriteStream(dest);
    var request = http.get(url, function(response) {

        // check if response is success
        if (response.statusCode !== 200) {
            return cb('Response status was ' + response.statusCode);
        }

        response.pipe(file);

        file.on('finish', function() {
            file.close(cb);  // close() is async, call cb after close completes.
        });
    });

    // check for request error too
    request.on('error', function (err) {
        fs.unlink(dest);
        return cb(err.message);
    });

    file.on('error', function(err) { // Handle errors
        fs.unlink(dest); // Delete the file async. (But we don't check the result) 
        return cb(err.message);
    });
};

Pomimo względnej prostoty tego kodu, radzę użyć request module , ponieważ obsługuje wiele innych protokołów (hello HTTPS!), które nie są natywnie obsługiwane przez http.

To byłoby zrobione tak:

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

var download = function(url, dest, cb) {
    var file = fs.createWriteStream(dest);
    var sendReq = request.get(url);

    // verify response code
    sendReq.on('response', function(response) {
        if (response.statusCode !== 200) {
            return cb('Response status was ' + response.statusCode);
        }
    });

    // check for request errors
    sendReq.on('error', function (err) {
        fs.unlink(dest);
        return cb(err.message);
    });

    sendReq.pipe(file);

    file.on('finish', function() {
        file.close(cb);  // close() is async, call cb after close completes.
    });

    file.on('error', function(err) { // Handle errors
        fs.unlink(dest); // Delete the file async. (But we don't check the result)
        return cb(err.message);
    });
};
 50
Author: Buzut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-22 01:53:27

Odpowiedź Gfxmonka ma bardzo ścisły wyścig danych między wywołaniem zwrotnym a zakończeniem file.close(). file.close() faktycznie pobiera callback, który jest wywoływany po zakończeniu zamknięcia. W przeciwnym razie natychmiastowe użycie pliku może się nie udać (bardzo rzadko!).

Kompletne rozwiązanie to:

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

Bez czekania na zdarzenie finish, naiwne skrypty mogą skończyć z niekompletnym plikiem. Bez planowania wywołania zwrotnego cb przez close, możesz uzyskać wyścig między dostępem do pliku a plikiem właściwie jestem gotowy.

 37
Author: Augusto Roman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-02 20:32:07

Rozwiązanie z timeoutem, zapobiega wyciekowi pamięci:

Poniższy kod opiera się na odpowiedzi Brandona Tilleya :

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

Nie twórz pliku, Gdy pojawi się błąd, i korzystaj z timeout, aby zamknąć żądanie po sekundzie X.

 14
Author: Hors Sujet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-02 19:11:12

Dla tych, którzy przyszli w poszukiwaniu obietnicy w stylu es6, myślę, że byłoby to coś w stylu:

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));
 12
Author: mido,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-30 07:49:28

Może węzeł.js się zmienił, ale wydaje się, że są pewne problemy z innymi rozwiązaniami (używając node v8.1.2):

  1. nie musisz wywoływać file.close() w zdarzeniu finish. Domyślnie fs.createWriteStream jest ustawione na autoClose: https://nodejs.org/api/fs.html#fs_fs_createwritestream_path_options
  2. file.close() powinno być wywołane w przypadku błędu. Może nie jest to potrzebne, gdy plik jest usuwany (unlink()), ale zwykle jest: https://nodejs.org/api/stream.html#stream_readable_pipe_destination_options
  3. plik Temp nie jest usuwany na statusCode !== 200
  4. fs.unlink() bez wywołania zwrotnego jest deprecated (outputs warning)
  5. Jeśli dest plik istnieje; jest nadpisywany

Poniżej znajduje się Zmodyfikowane rozwiązanie (za pomocą ES6 i promises), które rozwiązuje te problemy.

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);
            }
        });
    });
}
 9
Author: Bjarke Pjedsted,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-10 08:52:43

Kod Vince 'a Yuan' A jest świetny, ale wydaje się, że coś jest nie tak.

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);
        });
    });
}
 4
Author: weed,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-02 07:06:09

Możesz użyć https://github.com/douzi8/ajax-request#download

request.download('http://res.m.ctrip.com/html5/Content/images/57.png', 
  function(err, res, body) {}
);
 4
Author: douzi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-04 03:11:44
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));
 4
Author: kayz1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-18 21:14:47

Ścieżka: img Typ: 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;
}
 1
Author: databilim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-23 15:54:10

Jeśli używasz express użyj metody res. download (). w przeciwnym razie użyj modułu fs.

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

(lub)

   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");
          }
        });  
    }
 1
Author: KARTHIKEYAN.A,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-18 09:19:50

Pobierz za pomocą obietnicy, która rozwiązuje czytelny strumień. dodaj dodatkową logikę, aby obsłużyć przekierowanie.

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);
    }
});
 0
Author: wdanxna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-12 02:33:36
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);
  });
};
 0
Author: Alex Pilugin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-09 05:25:46

Możesz spróbować użyć res.redirect do adresu URL pobierania pliku https, a następnie zostanie pobrany plik.

Jak: res.redirect('https//static.file.com/file.txt');

 0
Author: Yin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-07 13:03:01

Bez biblioteki to może być buggy tylko zwrócić uwagę. Oto kilka:

Oto moja propozycja:

  • wywołanie narzędzia systemowego jak wget lub curl
  • użyj jakiegoś narzędzia, takiego jak node-wget-promise , które również jest bardzo proste w użyciu. var wget = require('node-wget-promise'); wget('http://nodejs.org/images/logo.svg');
 -1
Author: Geng Jiawen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-25 03:25:42
var requestModule=require("request");

requestModule(filePath).pipe(fs.createWriteStream('abc.zip'));
 -2
Author: Chandrakant Thakkar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-01 09:30:21

Możemy użyć modułu Pobierz węzeł i jego bardzo proste, patrz poniżej https://www.npmjs.com/package/download

 -2
Author: Iyyappan Subramani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-18 05:20:42