নোড.জেএস [বন্ধ] সহ চিত্রগুলি ডাউনলোড করা হচ্ছে


169

আমি নোড.জেএস ব্যবহার করে চিত্রগুলি ডাউনলোড করতে একটি স্ক্রিপ্ট লেখার চেষ্টা করছি। আমার এ পর্যন্ত যা আছে:

var maxLength = 10 // 10mb
var download = function(uri, callback) {
  http.request(uri)
    .on('response', function(res) {
      if (res.headers['content-length'] > maxLength*1024*1024) {
        callback(new Error('Image too large.'))
      } else if (!~[200, 304].indexOf(res.statusCode)) {
        callback(new Error('Received an invalid status code.'))
      } else if (!res.headers['content-type'].match(/image/)) {
        callback(new Error('Not an image.'))
      } else {
        var body = ''
        res.setEncoding('binary')
        res
          .on('error', function(err) {
            callback(err)
          })
          .on('data', function(chunk) {
            body += chunk
          })
          .on('end', function() {
            // What about Windows?!
            var path = '/tmp/' + Math.random().toString().split('.').pop()
            fs.writeFile(path, body, 'binary', function(err) {
              callback(err, path)
            })
          })
      }
    })
    .on('error', function(err) {
      callback(err)
    })
    .end();
}

আমি তবে এটিকে আরও দৃust় করতে চাই:

  1. এমন কি লাইব্রেরি রয়েছে যা এটি করে এবং এটি আরও ভাল করে?
  2. প্রতিক্রিয়া শিরোনামগুলি মিথ্যা বলে (দৈর্ঘ্য সম্পর্কে, সামগ্রীর ধরণের সম্পর্কে) কী এমন সুযোগ রয়েছে?
  3. আমার কি অন্যান্য স্ট্যাটাস কোডগুলি যত্নশীল হওয়া উচিত? পুনঃনির্দেশগুলি দিয়ে আমাকে বিরক্ত করা উচিত?
  4. আমি মনে করি যে আমি কোথাও পড়েছি যে binaryএনকোডিংটি হ্রাস করা হচ্ছে। আমি তখন কি করব?
  5. আমি কীভাবে এটি উইন্ডোতে কাজ করতে পারি?
  6. আপনি এই স্ক্রিপ্ট আরও ভাল করতে পারেন অন্য কোনও উপায়?

কেন: ইমগারের অনুরূপ বৈশিষ্ট্যের জন্য যেখানে ব্যবহারকারীরা আমাকে একটি ইউআরএল দিতে পারে, আমি সেই চিত্রটি ডাউনলোড করি এবং একাধিক আকারে চিত্রটি পুনরায় স্থাপন করি।

উত্তর:


401

আমি অনুরোধ মডিউলটি ব্যবহার করার পরামর্শ দেব । একটি ফাইল ডাউনলোড করা নিম্নলিখিত কোডের মতোই সহজ:

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.google.com/images/srpr/logo3w.png', 'google.png', function(){
  console.log('done');
});

1
শান্ত! আসলে ডাউনলোড করার আগে আকার এবং সামগ্রীর ধরণের কি চেক করার কোনও উপায় আছে?
জোনাথন ওং

2
এটি কোথায় ছবিগুলি ডাউনলোড করে?
গোফিলর্ড

17
আমার পক্ষে কাজ করছেন না (চিত্রটি কলুষিত হয়েছে
দারথ

2
@ গফিলর্ড এটি আপনার মূল ডিরেক্টরিতে চিত্রটি ডাউনলোড করুন।
ডাং

1
তারা যেখানে সংরক্ষণ করা হয়েছে তার অবস্থান পরিবর্তন করতে পারবেন? আপনি যদি একটি নির্দিষ্ট ফোল্ডারে তাদের চান?
কেএল012

33

আমি কিছুদিন আগে এই সমস্যায় পড়েছি, খাঁটি নোডজেএস উত্তরের জন্য আমি খণ্ডগুলিকে একত্রে একত্রিত করতে স্ট্রিম ব্যবহার করার পরামর্শ দেব।

var http = require('http'),                                                
    Stream = require('stream').Transform,                                  
    fs = require('fs');                                                    

var url = 'http://www.google.com/images/srpr/logo11w.png';                    

http.request(url, function(response) {                                        
  var data = new Stream();                                                    

  response.on('data', function(chunk) {                                       
    data.push(chunk);                                                         
  });                                                                         

  response.on('end', function() {                                             
    fs.writeFileSync('image.png', data.read());                               
  });                                                                         
}).end();

নতুন নোড সংস্করণগুলি বাইনারি স্ট্রিংগুলির সাথে ভালভাবে কাজ করবে না, সুতরাং বাইনারি ডেটার সাথে কাজ করার সময় স্ট্রিংগুলির সাথে অংশগুলি মার্জ করা ভাল ধারণা নয়।

* 'ডেটা.ড্রেড ()' ব্যবহার করার সময় কেবল সতর্কতা অবলম্বন করুন, এটি পরবর্তী 'পড়ুন') ক্রিয়াকলাপটি খালি করে দেবে। আপনি যদি এটি একাধিকবার ব্যবহার করতে চান তবে এটি কোথাও সংরক্ষণ করুন।


7
ডাউনলোডটি সরাসরি ডিস্কে স্ট্রিম করবেন না কেন?
জিওন

এটি একটি দুর্নীতিগ্রস্থ ফাইল তৈরি করার সাথে সাথে একসাথে চিংড়ি স্ট্রিংগুলিতে অনেক সমস্যা ছিল, তবে এটি এটি করেছিল
শাহো

27

অ্যাসিঙ্ক্রোনাস পরিবেশে আপনার পছন্দ অনুসারে চিত্রগুলি ডাউনলোড করতে আপনি অ্যাকজিওস ( নোড.জেএস এর জন্য একটি প্রতিশ্রুতি ভিত্তিক এইচটিটিপি ক্লায়েন্ট) ব্যবহার করতে পারেন :

npm i axios

তারপরে, আপনি চিত্রগুলি ডাউনলোড শুরু করতে নিম্নলিখিত মৌলিক উদাহরণটি ব্যবহার করতে পারেন:

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

/* ============================================================
  Function: Download Image
============================================================ */

const download_image = (url, image_path) =>
  axios({
    url,
    responseType: 'stream',
  }).then(
    response =>
      new Promise((resolve, reject) => {
        response.data
          .pipe(fs.createWriteStream(image_path))
          .on('finish', () => resolve())
          .on('error', e => reject(e));
      }),
  );

/* ============================================================
  Download Images in Order
============================================================ */

(async () => {
  let example_image_1 = await download_image('https://example.com/test-1.png', 'example-1.png');

  console.log(example_image_1.status); // true
  console.log(example_image_1.error); // ''

  let example_image_2 = await download_image('https://example.com/does-not-exist.png', 'example-2.png');

  console.log(example_image_2.status); // false
  console.log(example_image_2.error); // 'Error: Request failed with status code 404'

  let example_image_3 = await download_image('https://example.com/test-3.png', 'example-3.png');

  console.log(example_image_3.status); // true
  console.log(example_image_3.error); // ''
})();

2
দুর্দান্ত উদাহরণ! তবে সবেমাত্র পঠনযোগ্য কোড, স্ট্যান্ডার্ড স্টাইলটি চেষ্টা করুন : ডি
ক্যামহাইট

3
@ ক্যামহাইট আমি সেমিকোলন পছন্দ করি । ;)
গ্র্যান্ট মিলার

1
আপনার সত্যই 'সমাপ্তি' এবং 'ত্রুটি' ইভেন্টগুলি লেখার স্ট্রিমের সাথে সংযুক্ত করা উচিত, প্রতিশ্রুতিতে এগুলি মোড়ানো এবং প্রতিশ্রুতি ফিরিয়ে দেওয়া উচিত। অন্যথায় আপনি এমন কোনও চিত্র অ্যাক্সেস করার চেষ্টা করতে পারেন যা এখনও সম্পূর্ণ ডাউনলোড করা হয়নি।
jwerre

অপেক্ষা কি অ্যাক্সেস করার চেষ্টা করার আগে চিত্রটি সম্পূর্ণ ডাউনলোড হয়ে যায় তা নিশ্চিত করে না? @ জোভেরে
ফ্যাব্রিকিও

@ জ্যাভেরে @ ফ্যাব্রিকিওজি download_imageফিরে আসা প্রতিশ্রুতির জন্য 'সমাপ্তি' এবং 'ত্রুটি' ইভেন্টটি ক্যাপচারের জন্য ফাংশনটি আপডেট করেছি
বিনো টুং

10

আপনি যদি অগ্রগতি ডাউনলোড করতে চান তবে এটি ব্যবহার করে দেখুন:

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

module.exports = function (uri, path, onProgress, onResponse, onError, onEnd) {
    progress(request(uri))
    .on('progress', onProgress)
    .on('response', onResponse)
    .on('error', onError)
    .on('end', onEnd)
    .pipe(fs.createWriteStream(path))
};

ব্যবহারবিধি:

  var download = require('../lib/download');
  download("https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png", "~/download/logo.png", function (state) {
            console.log("progress", state);
        }, function (response) {
            console.log("status code", response.statusCode);
        }, function (error) {
            console.log("error", error);
        }, function () {
            console.log("done");
        });

দ্রষ্টব্য: আপনার অনুরোধ এবং অনুরোধ-অগ্রগতি মডিউল উভয়ই ইনস্টল করা উচিত:

npm install request request-progress --save

2
এটি দুর্দান্ত কাজ করেছে তবে statusCodeচেক যুক্ত করার পরামর্শ দিতে চেয়েছিল । উদাহরণস্বরূপ একটি 500 স্ট্যাটাস কোড, হিট করবে না 'on("error", e)on('response', (response) => console.error(response.statusCode))এটি যুক্ত করে এটি ডিবাগিংকে ব্যাপকভাবে সহায়তা করে
মেটাস্কিব

1
আপনি আমার উত্তরটি সম্পাদনা করতে পারেন :)
ফরিদ অ্যালামনোর্মি

4

উপরের ভিত্তিতে বিল্ডিং, কারও যদি লেখার / পড়ার স্ট্রিমগুলিতে ত্রুটিগুলি পরিচালনা করতে হয় তবে আমি এই সংস্করণটি ব্যবহার করেছি। stream.read()লেখার ত্রুটির ক্ষেত্রে নোট করুন , এটি প্রয়োজনীয় যাতে আমরা পড়া শেষ করতে এবং closeপড়ার স্ট্রিমটিতে ট্রিগার করতে পারি ।

var download = function(uri, filename, callback){
  request.head(uri, function(err, res, body){
    if (err) callback(err, filename);
    else {
        var stream = request(uri);
        stream.pipe(
            fs.createWriteStream(filename)
                .on('error', function(err){
                    callback(error, filename);
                    stream.read();
                })
            )
        .on('close', function() {
            callback(null, filename);
        });
    }
  });
};

2
stream.read()পুরানো বলে মনে হচ্ছে, একটি ত্রুটি ছুঁড়েছেnot a function
বেনডুলাম

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

var Stream = require('stream').Transform;

var downloadImageToUrl = (url, filename, callback) => {

    var client = http;
    if (url.toString().indexOf("https") === 0){
      client = https;
     }

    client.request(url, function(response) {                                        
      var data = new Stream();                                                    

      response.on('data', function(chunk) {                                       
         data.push(chunk);                                                         
      });                                                                         

      response.on('end', function() {                                             
         fs.writeFileSync(filename, data.read());                               
      });                                                                         
   }).end();
};

downloadImageToUrl('https://www.google.com/images/srpr/logo11w.png', 'public/uploads/users/abc.jpg');

1
আপনার ফাংশন
কলব্যাকটি

4

এটি সিজারির উত্তরের একটি এক্সটেনশন। আপনি যদি এটি কোনও নির্দিষ্ট ডিরেক্টরিতে ডাউনলোড করতে চান তবে এটি ব্যবহার করুন। এছাড়াও, var এর পরিবর্তে কনস্ট ব্যবহার করুন। এটি এইভাবে নিরাপদ।

const fs = require('fs');
const request = require('request');
var download = function(uri, filename, callback){
  request.head(uri, function(err, res, body){    
    request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
  });
};

download('https://www.google.com/images/srpr/logo3w.png', './images/google.png', function(){
  console.log('done');
});
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.