আনার জন্য অগ্রগতি সূচকগুলি আপলোড করবেন?


106

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

আমি এখনও অবধি খুঁজে পাওয়া এটিই কেবল রেফারেন্স , যা বলে:

অগ্রগতি ইভেন্টগুলি একটি উচ্চ স্তরের বৈশিষ্ট্য যা আপাতত আনতে পারে না। আপনি Content-Lengthশিরোনাম দেখে এবং প্রাপ্ত বাইটগুলি পর্যবেক্ষণ করতে একটি পাস-থ্রো স্টিম ব্যবহার করে নিজের তৈরি করতে পারেন ।

এর অর্থ আপনি কোনও প্রতিক্রিয়া ছাড়াই স্পষ্টভাবে প্রতিক্রিয়াগুলি পরিচালনা করতে পারেন Content-Length। এবং অবশ্যই, এমনকি যদি Content-Lengthএটি মিথ্যা হতে পারে। স্ট্রিমের সাহায্যে আপনি চাইলেও এই মিথ্যাগুলি পরিচালনা করতে পারেন।

আমি কীভাবে প্রেরিত "বাইটগুলি পর্যবেক্ষণ করতে একটি পাস-থ্রিম" লিখব? যদি এটি কোনও প্রকারের তফাত সৃষ্টি করে, আমি ব্রাউজার থেকে পাওয়ার ইমেজ আপলোডগুলিতে এটি করার চেষ্টা করছি ক্লাউডাইনারিতে

উল্লেখ্য : আমি না আগ্রহী Cloudinary জাতীয় গ্রন্থাগার , যেমন এটি jQuery উপর নির্ভর করে এবং আমার অ্যাপ্লিকেশন না। আমি নেটিভ জাভাস্ক্রিপ্ট এবং fetchগিথুবের পলিফিল দিয়ে এটি করার জন্য প্রয়োজনীয় স্ট্রিম প্রসেসিংয়ে কেবল আগ্রহী ।


https://fetch.spec.whatwg.org/#fetch-api


4
@ ম্যাগিক্স দেখুন ফেচটি বাতিল করা হচ্ছে : নেক্সট জেনারেশন # 447
অতিথি 271314

উত্তর:


46

স্ট্রিমগুলি ওয়েব প্ল্যাটফর্মে অবতরণ করতে শুরু করেছে ( https://jakearchibald.com/2016/streams-ftw/ ) তবে এখনও এটি প্রাথমিক দিনগুলি।

শীঘ্রই আপনি একটি অনুরোধের মূল হিসাবে একটি স্ট্রিম সরবরাহ করতে সক্ষম হবেন, তবে এই স্রোতের ব্যবহার আপলোড করা বাইটগুলির সাথে সম্পর্কিত কিনা তা প্রকাশ্য প্রশ্ন।

বিশেষভাবে পুনঃনির্দেশগুলির ফলে ডেটাটিকে নতুন জায়গায় পুনঃপ্রেরণ করা যেতে পারে তবে স্ট্রিমগুলি "পুনরায় আরম্ভ করতে পারে না"। আমরা দেহটিকে কলব্যাকে রূপান্তর করে এটিকে সংশোধন করতে পারি যা একাধিকবার বলা যেতে পারে, তবে আমাদের নিশ্চিত হওয়া দরকার যে পুনর্নির্দেশের সংখ্যাটি প্রকাশ করা কোনও সুরক্ষা ফাঁস নয়, যেহেতু প্ল্যাটফর্মে জেএস এটিই প্রথম হতে পারে এটি সনাক্ত করুন

কেউ কেউ প্রশ্ন তুলছেন যে এটি আপলোড করা বাইটগুলির সাথে স্ট্রিম খরচ সংযুক্ত করে তোলাও বুদ্ধিমান।

দীর্ঘ গল্প সংক্ষিপ্ত: এটি এখনও সম্ভব নয়, তবে ভবিষ্যতে এটি স্ট্রিমের মাধ্যমে পরিচালনা করা হবে, বা কোনও ধরণের উচ্চ-স্তরের কলব্যাকটি এতে প্রবেশ করবে fetch()


7
খুব খারাপ. আপাতত এটি গ্রহণ করা, কিন্তু যখন এটি বাস্তবতা হয়ে ওঠে, আমি আশা করি যে অন্য কেউ একটি আপডেট সমাধান পোস্ট করবেন! :)
নীজার

4
আপডেট - স্ট্রিম ব্যবহার করে ফেচ এপিআইয়ের সাথে অগ্রগতি দেখানো হচ্ছে - twitter.com/umaar/status/917789464658890753/photo/1
এটায়ান পিয়ার

4
পছন্দ করুন একই ধরণের জিনিস আপলোড করার জন্য কাজ করবে, যেমন পোস্ট?
মাইকেল 22

4
@ আইটানপীর তবে প্রশ্ন আপলোডের অগ্রগতির বিষয়ে, ডাউনলোডে নয়
জন বালভিন আরিয়াস

4
এটি এখন 2020, এখনও কেন এটি করার কোনও উপায় নেই :(
এমএইচএ

25

আমার সমাধানটি হল অক্ষগুলি ব্যবহার করা , যা এটি বেশ ভালভাবে সমর্থন করে:

      axios.request( {
        method: "post", 
        url: "/aaa", 
        data: myData, 
        onUploadProgress: (p) => {
          console.log(p); 
          //this.setState({
            //fileprogress: p.loaded / p.total
          //})
        }


      }).then (data => {
        //this.setState({
          //fileprogress: 1.0,
        //})
      })

গিথুবকে প্রতিক্রিয়া জানিয়ে এটি ব্যবহার করার জন্য আমার উদাহরণ রয়েছে


4
এটি আমার সমাধানও ছিল। অ্যাকজিওসগুলি সত্যই ভালভাবে ছাঁচে ফিট করে।
জেসন রাইস

4
কি axiosব্যবহার fetchবা XMLHttpRequestঅধীনে-ফণা?
দাই

4
এক্সএমএলএইচটিপিআরকোয়েস্ট। আপনি যদি এটিকে স্থানীয় নেতিবাচক প্রতিক্রিয়া হিসাবে ব্যবহার করে থাকেন তবে সাবধান হন XMLHttpRequest আনার সাথে তুলনা করার সময় বড় জসন প্রতিক্রিয়াগুলি পার্স করতে খুব ধীর বলে মনে হচ্ছে (প্রায় 10 গুণ ধীর এবং এটি পুরো ইউআই থ্রেডকে হিমায়িত করে)।
ক্রিশ্চিয়ানো কোয়েলহো

29
প্রশ্নের উত্তর দেয় না! যদি প্রশ্নটি হয় "আপনি y তে এক্স কী করবেন?" "পরিবর্তে x in z" বলা কোনও গ্রহণযোগ্য উত্তর নয়।
ডেরেক হেন্ডারসন

4
এটি প্রশ্নের উত্তর দেয় না, বিশেষত কারণ হুডের নীচে axiosব্যবহার করে না fetchএবং এর কোনও সমর্থন নেই। আমি আক্ষরিকভাবে এখন তাদের জন্য এটি লেখার ।
সাগামমন

7

আমি মনে করি না এটি সম্ভব। খসড়াটিতে বলা হয়েছে:

অগ্রগতির অনুরোধ করার সময় এটিতে [ এক্সএইচআরের তুলনায় ] অভাব রয়েছে


(পুরানো উত্তর): ফেচ এপিআই অধ্যায়ের
প্রথম উদাহরণটি কীভাবে তা সম্পর্কে কিছুটা অন্তর্দৃষ্টি দেয়:

আপনি যদি ক্রমবর্ধমানভাবে বডি ডেটা পেতে চান:

function consume(reader) {
  var total = 0
  return new Promise((resolve, reject) => {
    function pump() {
      reader.read().then(({done, value}) => {
        if (done) {
          resolve()
          return
        }
        total += value.byteLength
        log(`received ${value.byteLength} bytes (${total} bytes in total)`)
        pump()
      }).catch(reject)
    }
    pump()
  })
}

fetch("/music/pk/altes-kamuffel.flac")
  .then(res => consume(res.body.getReader()))
  .then(() => log("consumed the entire body without keeping the whole thing in memory!"))
  .catch(e => log("something went wrong: " + e))

Promiseকনস্ট্রাক্টর অ্যান্টিপ্যাটার্ন ব্যবহার ছাড়াও আপনি এটি দেখতে পারেনresponse.body এটি একটি স্ট্রিম যা থেকে আপনি একটি রিডার ব্যবহার করে বাইট করে বাইট পড়তে পারেন, এবং আপনি কোনও ইভেন্টে গুলি যার যার (উদাহরণস্বরূপ অগ্রগতি লগইন করুন)।

যাইহোক, স্ট্রিমস অনুমানটি বেশ সমাপ্ত বলে মনে হচ্ছে না এবং এটি ইতিমধ্যে কোনও আনতে বাস্তবায়নে কাজ করে কিনা তা আমার কোনও ধারণা নেই।


14
যদি আমি সেই উদাহরণটি সঠিকভাবে পড়ি তবে এটি কোনও ফাইলের মাধ্যমে ডাউনলোড করার জন্য fetch। আমি কোনও ফাইল আপলোড করার জন্য অগ্রগতি সূচকগুলিতে আগ্রহী ।
নীজার

উফফ, উক্তিটি বাইট গ্রহণের বিষয়ে কথা বলে , যা আমাকে বিভ্রান্ত করেছিল।
বার্গি 0

4
@ বার্গি নোট, Promiseকনস্ট্রাক্টর দরকার নেই। Response.body.getReader()ফেরত a Promiseবৃহত আকারের জসন ডাউনলোড করার সময় আনকচড রেঞ্জেররার কীভাবে সমাধান করবেন তা
গেস্ট 271314

4
@ গেস্ট 271314 হ্যাঁ, আমি এটিকে ইতিমধ্যে উদ্ধৃতিটির উত্সে স্থির করেছি । এবং না, getReaderকোনও প্রতিশ্রুতি দেয় না। আপনার লিঙ্ক করা পোস্টটির সাথে এর কী আছে তা ধারণা নেই।
বার্গি

@Bergi হ্যাঁ, আপনি সঠিক .getReader()'র .read()পদ্ধতি ফেরৎ Promise। এটাই জানাতে চাইছিল। লিঙ্কটি এই অনুচ্ছেদে আরও প্রমাণিত হয়েছে যে ডাউনলোডের জন্য যদি অগ্রগতি পরীক্ষা করা যায় তবে আপলোডের জন্য অগ্রগতি পরীক্ষা করা যেতে পারে। এমন একটি প্যাটার্ন একসাথে রাখুন যা প্রত্যাশিত ফলাফলটি প্রশংসনীয় ডিগ্রীতে প্রত্যাবর্তন করে; এটি fetch()আপলোডের জন্য অগ্রগতি । একটি উপায় খুঁজে পেলাম না echoএকটি Blobবা Filejsfiddle এ বস্তু, সম্ভবত কিছু সহজ অনুপস্থিত। localhostনেটওয়ার্কের অবস্থার নকল না করে খুব দ্রুত আপলোড ফাইলে পরীক্ষা করা ; যদিও স্রেফ মনে আছে Network throttling
অতিথি 271314

7

আপডেট: গ্রহণযোগ্য উত্তর হিসাবে বলা এখন এটি অসম্ভব। তবে নীচের কোডটি কিছু সময়ের জন্য আমাদের সমস্যা পরিচালনা করেছে। আমার যুক্ত করা উচিত যে কমপক্ষে আমাদের এমন একটি লাইব্রেরি ব্যবহার করতে হবে যা এক্সএমএলএইচটিপিআরকিউস্টের ভিত্তিতে রয়েছে।

const response = await fetch(url);
const total = Number(response.headers.get('content-length'));

const reader = response.body.getReader();
let bytesReceived = 0;
while (true) {
    const result = await reader.read();
    if (result.done) {
        console.log('Fetch complete');
        break;
    }
    bytesReceived += result.value.length;
    console.log('Received', bytesReceived, 'bytes of data so far');
}

এই লিঙ্কটি ধন্যবাদ: https://jakearchibald.com/2016/streams-ftw/


4
দুর্দান্ত, তবে এটি কি আপলোডগুলিতেও প্রযোজ্য?
কার্নেল

@ কার্নেল আমি এটি চেষ্টা করার চেষ্টা করেছি কিন্তু আমি এটি করতে সক্ষম হইনি। এবং আমি আপলোডের জন্য এটি করার একটি উপায়ও খুঁজতে চাই।
হোসেইনম্প্প 76

4
content-length! == শরীরের দৈর্ঘ্য। যখন http সংক্ষেপণ ব্যবহার করা হয় (বড় ডাউনলোডের জন্য সাধারণ), বিষয়বস্তুর দৈর্ঘ্যটি http সংক্ষেপণের পরে আকার হয়, যখন ফাইলটি বের করার পরে দৈর্ঘ্য আকার হয়।
ফেরিবিগ

4
আপনার কোডটি ধরে নিয়েছে যে বিষয়বস্তু শিরোনামের দৈর্ঘ্যটি আনতে হবে এমন বাইটের পরিমাণ নির্দিষ্ট করে। এটি সর্বদা সত্য নয়, সুতরাং আপনার কোডটি ব্যবহারকারীর কাছে অগ্রগতি দেখাতে পারে না, কারণ bytesReceivedএটি বড় হয়ে যায়total
ফেরিবিগ

4
তদুপরি, এমনকি ব্রাউজারটি আসল সামগ্রীর দৈর্ঘ্য আগেও জানে না। আপনি যা যাচ্ছেন তা হ'ল একটি পোস্ট-সংক্ষেপণের অগ্রগতি সূচক। উদাহরণস্বরূপ, আপনি যদি অসমভাবে বিতরণ করা সংক্ষেপণ অনুপাত (কিছু ফাইল এলোমেলো, কিছু কম এনট্রপি) সহ একটি জিপ ফাইল ডাউনলোড করেন তবে আপনি লক্ষ্য করবেন যে অগ্রগতি সূচকটি গুরুতরভাবে স্কুড রয়েছে।
elslooo

4

যেহেতু উত্তরগুলির কোনওটিই সমস্যার সমাধান করে না।

কেবল বাস্তবায়নের জন্য, আপনি কিছু ছোট ছোট পরিচিত আকারের সাথে আপলোডের গতি সনাক্ত করতে পারেন এবং আপলোডের সময়টি সামগ্রী-দৈর্ঘ্য / আপলোড-গতির সাথে গণনা করা যায়। আপনি অনুমান হিসাবে এই সময় ব্যবহার করতে পারেন।


4
আমরা একটি রিয়েলটাইম সমাধানের জন্য অপেক্ষা করার সময় ব্যবহার করতে খুব চালাক, দুর্দান্ত কৌশল :)
ম্যাগিক্স


2

new Request()কনস্ট্রাক্টরকে ব্যবহার করে তারপরে Request.bodyUsed Booleanঅ্যাট্রিবিউটটি পরীক্ষা করা সম্ভব সম্ভাব্য কাজ হতে পারে

bodyUsedঅ্যাট্রিবিউট এর সংগ্রহকারী যদি সত্যি ফিরে আসবে disturbedঅন্যথায়, এবং মিথ্যা।

স্ট্রিম কিনা তা নির্ধারণ করা distributed

Bodyমিক্সিন প্রয়োগকারী একটি বস্তু বলা হয় disturbedযদি bodyএটি নন এবং নল streamহয় disturbed

সমান হলে এর পুনরাবৃত্ত কলটিতে শৃঙ্খলযুক্ত fetch() Promiseথেকে ফিরে আসুন ।.then().read()ReadableStreamRequest.bodyUsedtrue

দ্রষ্টব্য, Request.bodyবাইটগুলি শেষ বিন্দুতে প্রবাহিত হওয়ায় পদ্ধতির বাইটগুলি পড়া হয় না । এছাড়াও, ব্রাউজারে কোনও প্রতিক্রিয়া পূর্ণরূপে ফেরার আগে আপলোডটি ভালভাবে সম্পূর্ণ হতে পারে।

const [input, progress, label] = [
  document.querySelector("input")
  , document.querySelector("progress")
  , document.querySelector("label")
];

const url = "/path/to/server/";

input.onmousedown = () => {
  label.innerHTML = "";
  progress.value = "0"
};

input.onchange = (event) => {

  const file = event.target.files[0];
  const filename = file.name;
  progress.max = file.size;

  const request = new Request(url, {
    method: "POST",
    body: file,
    cache: "no-store"
  });

  const upload = settings => fetch(settings);

  const uploadProgress = new ReadableStream({
    start(controller) {
        console.log("starting upload, request.bodyUsed:", request.bodyUsed);
        controller.enqueue(request.bodyUsed);
    },
    pull(controller) {
      if (request.bodyUsed) {
        controller.close();
      }
      controller.enqueue(request.bodyUsed);
      console.log("pull, request.bodyUsed:", request.bodyUsed);
    },
    cancel(reason) {
      console.log(reason);
    }
  });

  const [fileUpload, reader] = [
    upload(request)
    .catch(e => {
      reader.cancel();
      throw e
    })
    , uploadProgress.getReader()
  ];

  const processUploadRequest = ({value, done}) => {
    if (value || done) {
      console.log("upload complete, request.bodyUsed:", request.bodyUsed);
      // set `progress.value` to `progress.max` here 
      // if not awaiting server response
      // progress.value = progress.max;
      return reader.closed.then(() => fileUpload);
    }
    console.log("upload progress:", value);
    progress.value = +progress.value + 1;
    return reader.read().then(result => processUploadRequest(result));
  };

  reader.read().then(({value, done}) => processUploadRequest({value,done}))
  .then(response => response.text())
  .then(text => {
    console.log("response:", text);
    progress.value = progress.max;
    input.value = "";
  })
  .catch(err => console.log("upload error:", err));

}

-2
const req = await fetch('./foo.json');
const total = Number(req.headers.get('content-length'));
let loaded = 0;
for await(const {length} of req.body.getReader()) {
  loaded = += length;
  const progress = ((loaded / total) * 100).toFixed(2); // toFixed(2) means two digits after floating point
  console.log(`${progress}%`); // or yourDiv.textContent = `${progress}%`;
}

পুরো উত্তরের জন্য আমি বেঞ্জামিন গ্রুইনবাউমকে কৃতিত্ব দিতে চাই। কারণ আমি তাঁর বক্তৃতা থেকে এটি শিখেছি।
লিওন গিলিয়াডভ

@ লিওনগিলিয়াডভ লেকচারটি কি কোথাও অনলাইনে পাওয়া যায়? উত্স একটি লিঙ্ক সুন্দর হবে।
মার্ক অ্যামেরি

@ মার্ক অ্যামেরি এটি হ'ল: youtube.com/watch?v=Ja8GKkxahCo (বক্তৃতাটি হিব্রু ভাষায় দেওয়া হয়েছিল)
লিওন গিলিয়াডভ

13
প্রশ্ন আপলোড সম্পর্কে, ডাউনলোড নয়।
সার্নিহ

আনার অগ্রগতির সমস্যা হ'ল আপনি যখন আপলোড করতে চান (ডাউনলোড করার ক্ষেত্রে কোনও সমস্যা নেই)
কামিল কিয়েস্কেউস্কি

-6

কী অংশ ReadableStream « obj_response .body»।

নমুনা:

let parse=_/*result*/=>{
  console.log(_)
  //...
  return /*cont?*/_.value?true:false
}

fetch('').
then(_=>( a/*!*/=_.body.getReader(), b/*!*/=z=>a.read().then(parse).then(_=>(_?b:z=>z)()), b() ))

আপনি এটি একটি বিশাল পৃষ্ঠায় উদাহরণস্বরূপ https://html.spec.whatwg.org/ এবং https://html.spec.whatwg.org/print.pdf এ চলমান পরীক্ষা করতে পারেন । CtrlShiftJ এবং কোডটি লোড করুন।

(ক্রোমে পরীক্ষিত)


4
এই উত্তরটি বিয়োগ পয়েন্ট পেয়েছে তবে কেউ কেন বিয়োগ বিন্দু দেয় তা ব্যাখ্যা করে না - তাই আমি +1 দিই
কামিল কিয়েস্কেউস্কি

4
এটি আমার কাছ থেকে একটি -1 পায় কারণ এটি আপলোডের ক্ষেত্রে প্রাসঙ্গিক নয় ।
ব্র্যাড

আমি বিশ্বাস করি এটি -১ পেয়েছে কারণ মনে হচ্ছে এটি
সংশোধিত
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.