XMLHttpRequest Level 2 ( যেটাকে আমি Ajax2 বলি) , দিয়ে ফাইল আপলোড

HTML5 এ এখন XMLHttpRequest Level 2 নতুন যোগ হবার কারণে আমরা Ajax দিয়ে ফাইল আপলোড করতে পারি, যা আমরা আগে ফ্লাশ দিয়ে করতাম 😥 . ফাইল আপলোড করার জন্যে সময় সিলেক্টেড ফাইলের ইনফো রিড করা এখন খুব সহজেই করা যায়। আর আপনি যদি File API নিয়ে কাজ করতে চান তবে আপনাকে File API টা পড়ে নিতে হবে।

আপনার ব্রাউজার XMLHttpRequest Level 2 সাপোর্ট করে কিনা তা আপনি চেক করে নিন
( আমি Firefox 7.0, Chrome 16, Safari 5 ব্যবহার করি )

যাই হোক আমি এখন একটা ফাইল আপলোড করতে
ফাইল ইনফো রিড, বাইট মাপা, আপলোড স্পিড ইত্যাদি করার চেস্টা করব।
তবে চলুন আগে HTML টা লিখে ফেলি:

<form id="form1" enctype="multipart/form-data" method="post" action="upload.php">
   <label for="fileToUpload">Select a File to Upload</label><br />
   <input type="file" name="fileToUpload" id="fileToUpload">
   <input type="button"  value="Upload" />
  </form>

আপলোড Cancel করার একটা অপশন ও লাগবে আমার, তো চলুন ওটাও দিই

<form id="form1" enctype="multipart/form-data" method="post" action="upload.php">
<label for="fileToUpload">Select a File to Upload</label>
<input type="file" name="fileToUpload" id="fileToUpload"> <input type="button"  value="Upload" />

// এই লিন্কে ক্লিক করে আমরা আপলোডটা cancel করে দিব<a href="javascript:;">Cancel</a> </form>

ফাইল রিড করে ফাইলের ইনফো গুলা show করব,ওটাও দিই

<form id="form1" enctype="multipart/form-data" method="post" action="upload.php">
<label for="fileToUpload">Select a File to Upload</label><br />
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="button"  value="Upload" />
<a href="javascript:;">Cancel</a>
</form>

 

<div id="fileName"></div> <!-- ফাইল সিলেক্ট করলে ফাইলের নামটা এখানে দেখাবে --></p>
<div id="fileSize"></div> <!-- ফাইলের সাইজ দেখাবে --></p>
<div id="fileType"></div> <!-- ফাইলের MIME Type টা দেখাবে --></p>

এবার ফাইল আপলোড প্রগ্রেসটা শো করার জন্যে একটা HTML DIV টা করি

<form id="form1" enctype="multipart/form-data" method="post" action="upload.php">
<label for="fileToUpload">Select a File to Upload</label><br />
<input type="file" name="fileToUpload" id="fileToUpload">
<input type="button"  value="Upload" />
<a href="javascript:;">Cancel</a>
</form>

 

<div id="fileName"></div>
<div id="fileSize"></div>
<div id="fileType"></div>
<div id="progressNumber"></div>

আমাদের সিম্পল ফাইল আপলোড UI  টা হল এইটুকু যেখানে আমরা

  1. একটা ফাইল সিলেক্ট করব
  2. ফাইল ইনফো দেখব
  3. আপলোড করব
  4. আপলোড প্রগ্রেস দেখব, বা আপলোড cancel করে দেব

আর এই এ্যাকশন গুলা করার জন্যে আমি জাভাস্ক্রিপ্ট ব্যবহার করছি, চলেন এবার জাভাস্ক্রিপ্ট টা লিখি
স্টেপ গুলা বলি কাজ শুরু হবে ফাইল সিলেক্ট করার পর:

  1.  বাইট গুলা সাজাব
  2.  আপলোড টাইম রিমেইনের জন্যে সেকেন্ডকে সুন্দর ভাবে টাইমে সাজাব
  3.  ফাইল সিলেক্ট করে ইনফো রিড করব
  4. স্পিড টেস্টার বানাব
  5.  আপলোড প্রগ্রেসটা বানাব
  6.  আপলোড কমপ্লিড, ফেইল, Cancel,  হলে কি মেসেজ দিবে তা তৈরি করব
  7. আপলোড Cancel একশন টা দেব
  8. XMLHttpRequest2 ব্যবহার করে ফাইল পাঠাব

বলে রাখি আমি জাভাস্ক্রিপ্টের অবজেক্ট ও অ্যারে গুলা রিড করার জন্যে একটা সিম্পল ফাংশন বানিয়েছিলাম ওটা ব্যবহার করি।
চলুন শুরু করি:

ফাংশনটা দিয়ে আমি জাভাস্ক্রিপ্টের অবজেক্ট ও অ্যারে গুলা রিড করি

function print_r(obj, show_as_alert)
{
var str='';
for(var prop in obj)
{
str+=prop + " : "+ obj[prop]+"\n\n";
}

if( show_as_alert==true ){  alert(str);  }
else { return(str);    }

}

বাইট গুলা সাজাব

function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
}

জাভাস্ক্রিপ্ট ম্যাথ সম্পর্কে আরো জানতে

আপলোড টাইম রিমেইনের জন্যে সেকেন্ডকে সুন্দর ভাবে টাইমে সাজাব

function secondsToTime(secs) {
var hr = Math.floor(secs / 3600);
var min = Math.floor((secs - (hr * 3600))/60);
var sec = Math.floor(secs - (hr * 3600) -  (min * 60));

if (hr < 10) {hr = "0" + hr; }
if (min < 10) {min = "0" + min;}
if (sec < 10) {sec = "0" + sec;}
if (hr) {hr = "00";}
return hr + ':' + min + ':' + sec;
}

ফাইল সিলেক্ট করে ইনফো রিড

function fileSelected() {
var file = document.getElementById('fileToUpload').files[0];
// আপাতত একটা ফাইল নিয়ে দেখি .files[0]
/** কি ইনফো আসল না আসল তা    print_r(file,true);  দিয়ে দেখতে পারেন
*/

 if (file) {
//   বাইটগুলাকে সাজালাম

 var fileSize = bytesToSize(file.size);</pre>
// ফাইল নেম শো করব

document.getElementById('fileName').innerHTML = 'Name: ' + file.name;</pre>
// ফাইল সাইজ  শো করব

document.getElementById('fileSize').innerHTML = 'Size: ' + fileSize;</pre>
//   ফাইল টাইপ  শো করব

 document.getElementById('fileType').innerHTML = 'Type: ' + file.type;
}
}

এবার কিছু গ্লোবাল ভেরিয়েবল ডিক্লেয়ার করি।


// কত বাইট আপলোড করা হল

var iBytesUploaded=0;
// টোটাল কত বাইট</p>

var iBytesTotal=0;
//  কত বাইট লোড করেছে

var iPreviousBytesLoaded=0;
//  XMLHTTPRequest2 অবজেক্টটা এই ভেরিয়েবলে সেভ রাখব,

var xhr;

একটা রিসেট ফাংশন করি যেন ফাইল আপলোড হবার পর বা ফাইল আপলোড Cancel হলে গ্লোবাল ভেরিয়েবল গুলো যেন রিসেট হয়ে যায়


function reset()
{
iBytesUploaded=0;
iBytesTotal=0;
iPreviousBytesLoaded=0;
xhr=null;
}

এবার ফাইল আপলোড ফাংশনটা করি,
এখানে একটা কথা বলে রাখি আমি ফরমের ডাটা পড়ার জন্যে FormData ব্যবহার করেছি।

function uploadFile() {
//  ফরম টা নিলাম

$form = document.getElementById('form1');
var fd = new FormData($form);
// গ্লোবাল ভেরিয়েবল xhr কে XMLHttpRequest() এর instance বানালাম
// print_r(xhr,true);  কি হল না হল print_r করে দেখুন

 xhr = new XMLHttpRequest();
// ফরমের একশনে যে ইউআরএলটা আছে ওতেই  আপলোডটা প্রসেস করব
$url = $form.getAttribute('action');
/** <em>addEventListener</em> এর সিনট্যাক্স          object.addEventListener (eventName, functionName, useCapture); // useCapture: true|false */</p>
// আপলোড প্রগ্রেসের সময় জাভাস্ক্রিপটের uploadProgress ফাংশন কল হবে

xhr.upload.addEventListener("progress", uploadProgress, false);
// লোড অর্থাৎ আপলোড সাকসেসফুলি হলে uploadComplete ফাংশন কল হবে

xhr.addEventListener("load", uploadComplete, false);</pre>
// এরর অর্থাৎ আপলোড করতে এরর আসলে uploadFailed ফাংশন কল হবে

xhr.addEventListener("error", uploadFailed, false);
// আপলোড Cancel হলে uploadCanceled ফাংশন কল হবে

xhr.addEventListener("abort", uploadCanceled, false);
/* Open এর সিনট্যাক্স: open(method, url, async, user, password)  যেসব মেথড ব্যবহার করা যায়: CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, TRACE, or TRACK */

 xhr.open("POST", $url);

xhr.send(fd);

}

এবার আপলোড Cancel করার ফাংশনটা দিই


function cancel() {
/** Cancel করার আগে কনফার্ম হবে, তার পর বর্তমান XMLHttpRequest যেটা আমরা xhr এ ভেরিএবলে রেখেছিলাম সেটার কাজ abort ফাংশন দ্বারা বন্ধ হয়ে যাবে</p>
*/

var s = confirm('R u sure?'); //
 if(s){  xhr.abort();  }
}

এবার আসুন uploadProgress, uploadComplete, uploadFailed, uploadCanceled ইত্যাদি  ফাংশন গুলি লিখে ফেলি

uploadProgress


function uploadProgress(evt) {

if (evt.lengthComputable) { //

/**
কতটুকু লোড হল তা iBytesUploaded ভেরিয়েবলে রাখলাম
*/
iBytesUploaded = evt.loaded;

/**
টোটাল সাইজ কত তা iBytesTotal ভেরিয়েবলে রাখলাম
*/
 iBytesTotal = evt.total;
/**  কত % কমপ্লিট হল  */
var percentComplete = Math.round(evt.loaded * 100 / evt.total);

 $c = percentComplete.toString();

document.getElementById('progressNumber').innerHTML = '<progress max="100" value="'+$c+'"></progress>'+ $c + '% completed || ' +"&nbsp;&nbsp;"+speed()+"  ";

}
else {
document.getElementById('progressNumber').innerHTML = '<progress max="100">' +"&nbsp;&nbsp;"+speed()+"  ";
}

}

uploadComplete


function uploadComplete(evt) {</pre>
/* আপলোড হবার পর সার্ভার থেকে যে রেসপন্সটা আসল তা Alert দিয়ে দেখাবে */</p>

reset();
alert(evt.target.responseText);
}

uploadFailed


>function uploadFailed(evt) {
reset();</pre>
alert("ফাইল আপলোডে গিট্টু লাইগছে, ২/৩ ঘন্টার আগে ছুটবনা :(");

}

uploadCanceled


function uploadCanceled(evt) {
reset();</pre>
alert("ঠিকাসে আপলোড করুম না");

}

এবার আসুন বিভিন্ন ইভেন্টে ফাংশন গুলো ডাক দিই


<form id="form1" enctype="multipart/form-data" method="post" action="upload.php">
<div>
<label for="fileToUpload">Select a File to Upload</label><br />

<!-- onchange অর্থাৎ যখন একটা ফাইল সিলেক্ট করা হবে তখন fileSelected() ফাংশনটা কল হবে -->
<input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/>

<!-- Cancel লিন্কে ক্লিকের পর cancel() ফাংশনটা কল হবে -->

<a href="javascript:;" onClick="cancel();">Cancel</a></div>
<div id="fileName"></div>
<div id="fileSize"></div>
<div id="fileType"></div>
<div>

<!-- Upload বাটনে ক্লিকের পর uploadFile() ফাংশনটা কল হবে -->

<input type="button" onclick="uploadFile()" value="Upload" />
</div>
<div id="progressNumber"></div>
</form>

পুরা কোড

<pre><!DOCTYPE html>
<html>
<head>
<title>Upload Files using XMLHttpRequest </title>
<script type="text/javascript">

function print_r(obj, show_alert) {
var str='';
for(var prop in obj)
{
str+=prop + " : "+ obj[prop]+"\n\n";
}

if( show_alert==true ){  alert(str);  }
else { return(str);    }

}

function secondsToTime(secs) { // we will use this function to convert seconds in normal time format

var hr = Math.floor(secs / 3600);
var min = Math.floor((secs - (hr * 3600))/60);
var sec = Math.floor(secs - (hr * 3600) -  (min * 60));

if (hr < 10) {hr = "0" + hr; }
if (min < 10) {min = "0" + min;}
if (sec < 10) {sec = "0" + sec;}
if (hr) {hr = "00";}
return hr + ':' + min + ':' + sec;
};

function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
};

var iBytesUploaded=0;
var iBytesTotal=0;
var iPreviousBytesLoaded=0;
var xhr;

function reset()
{
iBytesUploaded=0;
iBytesTotal=0;
iPreviousBytesLoaded=0;
xhr=null;

}

function speed()
{

var iCB = iBytesUploaded;
var iDiff = iCB - iPreviousBytesLoaded;

// if nothing new loaded - exit
if (iDiff == 0)
return '';

iPreviousBytesLoaded = iCB;
iDiff = iDiff * 2;
var iBytesRem = iBytesTotal - iPreviousBytesLoaded;
var secondsRemaining = iBytesRem / iDiff;

// update speed info
var iSpeed = iDiff.toString() + 'B/s';
if (iDiff > 1024 * 1024) {
iSpeed = (Math.round(iDiff * 100/(1024*1024))/100).toString() + 'MB/s';
} else if (iDiff > 1024) {
iSpeed =  (Math.round(iDiff * 100/1024)/100).toString() + 'KB/s';
}

return 'Total '+bytesToSize(iBytesTotal)+' || uploaded '+bytesToSize(iBytesUploaded)  +' || upload speed '+iSpeed+ ' || ' + secondsToTime(secondsRemaining)+' remainng. ';

}

function fileSelected() {
var file = document.getElementById('fileToUpload').files[0];

//alert(print_r(file));

if (file) {

var fileSize = bytesToSize(file.size);

document.getElementById('fileName').innerHTML = 'Name: ' + file.name;
document.getElementById('fileSize').innerHTML = 'Size: ' + fileSize;
document.getElementById('fileType').innerHTML = 'Type: ' + file.type;
}
}

function cancel()
{

var s = confirm('R u sure?');
if(s){  xhr.abort();  }

}

function uploadFile() {

$form = document.getElementById('form1');

var fd = new FormData($form);
//fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
xhr = new XMLHttpRequest();

//print_r(xhr.upload,true);

$url = $form.getAttribute('action');

// syntex of addEventListener:
// object.addEventListener (eventName, functionName, useCapture); // useCapture: true|false

xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.addEventListener("load", uploadComplete, false);
xhr.addEventListener("error", uploadFailed, false);
xhr.addEventListener("abort", uploadCanceled, false);
xhr.addEventListener("loadend", loadEnd, false);
xhr.open("POST", $url); // open(method, url, async, user, password)  method=CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, TRACE, or TRACK
xhr.send(fd);

}

function uploadProgress(evt) {
if (evt.lengthComputable) {

iBytesUploaded = evt.loaded;
iBytesTotal = evt.total;

var percentComplete = Math.round(evt.loaded * 100 / evt.total);

$c = percentComplete.toString();

document.getElementById('progressNumber').innerHTML = '<progress max="100" value="'+$c+'"></progress>'+ $c + '% completed || ' +"&nbsp;&nbsp;"+speed()+"  ";

}
else {
document.getElementById('progressNumber').innerHTML = '<progress max="100">' +"&nbsp;&nbsp;"+speed()+"  ";
}

}

function loadEnd()
{

document.getElementById('progressNumber').innerHTML = '<progress max="100" value="100"></progress> 100% '+"&nbsp;&nbsp;"+speed()+"  ";

}

function uploadComplete(evt) {
/* This event is raised when the server send back a response */

//print_r(evt.target.responseText,true);

reset();
alert(evt.target.responseText);
}

function uploadFailed(evt) {
reset();
alert("ফাইল আপলোডে গিট্টু লাইগছে, ২/৩ ঘন্টার আগে ছুটবনা :(");
}

function uploadCanceled(evt) {
reset();
alert("ঠিকাসে আপলোড করুম না");
}
</script>
</head>
<body>
<form id="form1" enctype="multipart/form-data" method="post" action="upload.php">
<div>
<label for="fileToUpload">Select a File to Upload</label>
<br />
<input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/>
<a href="javascript:;" onClick="cancel();">Cancel</a></div>
<div id="fileName"></div>
<div id="fileSize"></div>
<div id="fileType"></div>
<div>
<input type="button" onclick="uploadFile()" value="Upload" />
</div>
<div id="progressNumber"></div>
</p>
</form>
</body>
</html>

ডেমো দেখুন | ডাউনলোডান

Level 0

আমি ইমরান আহমেদ। বিশ্বের সর্ববৃহৎ বিজ্ঞান ও প্রযুক্তির সৌশল নেটওয়ার্ক - টেকটিউনস এ আমি 13 বছর 2 মাস যাবৎ যুক্ত আছি। টেকটিউনস আমি এ পর্যন্ত 2 টি টিউন ও 8 টি টিউমেন্ট করেছি। টেকটিউনসে আমার 0 ফলোয়ার আছে এবং আমি টেকটিউনসে 0 টিউনারকে ফলো করি।

:( :) :D


টিউনস


আরও টিউনস


টিউনারের আরও টিউনস


টিউমেন্টস

সিনট্যাক্স হাইলাইটার টা কিভাবে ব্যবহার করে আমি জানি না 🙁

    @ইমরান আহমেদ: বিভিন্ন প্রোগ্রামিং ল্যাঙ্গুয়েজের কোড যেমন HTML, CSS, JS, PHP ইত্যাদি কোড সুন্দর ও সঠিক ভাবে দেখাতে টেকটিউনসের রয়েছে নিজেস্ব “কোড হাইলাইটার”। টেকটিউনসের “কোড হাইলাইটার” কিভাবে ব্যবহার করতে হয় তা জানতে এই টিউনটি https://www.techtunes.io/web-design/tune-id/77692/ দেখুন।

    টেকটিউনস প্ল্যাটফরম সম্বন্ধে আরও জানতে ‘টেকটিউনস সজিপ্র’ https://www.techtunes.io/faq/ দেখুন।

ধন্যবাদ 🙂

Level 0

DARUN

সুন্দর টিউন আমার প্রিয়।