AJAX এবং jQuery এর সাথে HTML5 ফাইল আপলোড ব্যবহার করা


84

স্বীকারোক্তিজনকভাবে, স্ট্যাক ওভারফ্লোতে প্রায় একই রকম প্রশ্ন রয়েছে, তবে এটি আমার প্রয়োজনীয়তা পুরোপুরি মেটেনি বলে মনে হয়।

আমি যা করতে চাই তা এখানে:

  • একটি সম্পূর্ণ ফাইলের ডেটা আপলোড করুন যার এক টুকরো একটি ফাইল
  • কোডাইনাইটারের ফাইল আপলোড লাইব্রেরি নিয়ে কাজ করুন

এখানে অবধি সমস্ত কিছু ঠিক আছে। আমার প্রয়োজন হিসাবে ডেটা আমার ডাটাবেসে পাওয়া যায়। তবে আমি আমার ফর্মটি একটি এজেএক্স পোস্টের মাধ্যমে জমা দিতে চাই:

  • নেটিভ HTML5 ফাইল এপিআই ব্যবহার করে, ফ্ল্যাশ বা কোনও আইফ্রেমে সমাধান নয়
  • নিম্ন স্তরের .ajax()jQuery পদ্ধতির সাথে প্রাথমিকভাবে হস্তক্ষেপ করা

আমি মনে করি খাঁটি জাভাস্ক্রিপ্ট ব্যবহার করে যখন ক্ষেত্রের মান পরিবর্তিত হয় তখন ফাইলটি স্বয়ংক্রিয়ভাবে আপলোড করে কীভাবে করব তা আমি কল্পনা করতে পারি, তবে jQuery এ জমা দেওয়ার জন্য আমি সমস্ত কিছু বরং ঝাপিয়ে পড়েছি। আমি ভেবেছি ক্যোয়ারী স্ট্রিংগুলির মাধ্যমে এটি করা সম্ভব নয় কারণ আমার পুরো ফাইলটিটি পাস করার প্রয়োজন, তবে আমি এই মুহুর্তে কী করব সে সম্পর্কে কিছুটা হারিয়েছি।

এটি কি অর্জন করা যায়?


কোডিগিটার অংশটি সম্পর্কে আমার কোনও ধারণা নেই তবে jQuery অংশের জন্য এই প্লাগইনটি দেখুন
BalusC

উত্তর:


93

এটা খুব কঠিন না। প্রথমত, ফাইলরেডার ইন্টারফেসটি একবার দেখুন ।

সুতরাং, ফর্মটি জমা দেওয়ার পরে, জমা দেওয়ার প্রক্রিয়াটি ধরুন এবং

var file = document.getElementById('fileBox').files[0]; //Files[0] = 1st file
var reader = new FileReader();
reader.readAsText(file, 'UTF-8');
reader.onload = shipOff;
//reader.onloadstart = ...
//reader.onprogress = ... <-- Allows you to update a progress bar.
//reader.onabort = ...
//reader.onerror = ...
//reader.onloadend = ...


function shipOff(event) {
    var result = event.target.result;
    var fileName = document.getElementById('fileBox').files[0].name; //Should be 'picture.jpg'
    $.post('/myscript.php', { data: result, name: fileName }, continueSubmission);
}

তারপরে, সার্ভারে (যেমন myscript.php):

$data = $_POST['data'];
$fileName = $_POST['name'];
$serverFile = time().$fileName;
$fp = fopen('/uploads/'.$serverFile,'w'); //Prepends timestamp to prevent overwriting
fwrite($fp, $data);
fclose($fp);
$returnData = array( "serverFile" => $serverFile );
echo json_encode($returnData);

বা এটির মতো কিছু। আমি ভুল হতে পারে (এবং যদি আমি, দয়া করে, আমাকে সংশোধন), কিন্তু ভালো কিছু হিসাবে ফাইল সংরক্ষণ করা উচিত 1287916771myPicture.jpgমধ্যে /uploads/আপনার সার্ভার, এবং একটি JSON- পরিবর্তনশীল (ক করার সঙ্গে সাড়া উপর continueSubmission()ফাংশন) সার্ভার উপর ফাইলের নামের রয়েছে।

চেক আউট fwrite()এবং jQuery.post()

উপরে পৃষ্ঠায় এটি বিস্তারিত কীভাবে ব্যবহার করবেন তা readAsBinaryString(), readAsDataUrl()এবং readAsArrayBuffer()আপনার অন্য প্রয়োজনের জন্য (যেমন ছবি, ভিডিও, ইত্যাদি)।


আরে ক্লার্ক, আমি কি সঠিকভাবে বুঝতে পারি? এটি jQuery এর নিম্ন-স্তরের .জ্যাক্স হ্যান্ডলারকে বাইপাস করে ফাইল সিস্টেম থেকে ফাইলআরডার কনস্ট্রাক্টারে লোড হওয়ার সাথে সাথে আপলোড করা ফাইলটি প্রেরণ করবে। তারপরে বাকি ফর্মটি কি স্বাভাবিক হিসাবে জমা দেবে?
জোশুয়া কোডি

ঠিক আছে, তাই আমি আগে আমার বোঝার ভুল ছিল। এখন আমি একটি চিত্রের রিডএএসডাটাআরএল নিচ্ছি, এটি আমার ডায়াস্ট্রিংয়ে। জ্যাক্সে যুক্ত করে, এবং আমার সমস্ত তথ্য একসাথে জমা দিচ্ছি। আমার পূর্ববর্তী সমাধানে কোডআইগনিটারের ডিফল্ট ফাইল ইনপুট ক্লাস জড়িত যা $ _FILES ['ফিল্ড'] থেকে ডেটা ধরেছে, তাই দেখে মনে হচ্ছে বেস বেস image৪ চিত্রের ডেটা পার্স করার জন্য আমার আলাদা সমাধানে স্যুইচ করা দরকার। এখানে আপনার উত্তরকে সমর্থন করে, সে সম্পর্কে যে কোনও পরামর্শই স্বাগত জানানো হবে এবং একবার বাস্তবায়ন শেষ করার পরে আমি এটিকে সঠিক হিসাবে চিহ্নিত করব।
জোশুয়া কোডি

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

@ ক্লার্কফ, জমা দেওয়ার আগে আমাকে আপলোড করার দরকার নেই, আমি আপনার পূর্ববর্তী উদাহরণটি ভুল বুঝছিলাম :) তাই নিচে চলে যাওয়ার পরে এবং আমি ডাব্লু 3 এবং এইচটিএমএল 5 রকসে কিছুটা সময় কাটিয়েছি , আমি বুঝতে শুরু করেছি। আমি এই শট দেব এবং এখানে ফিরে আসব।
জোশুয়া কোডি

ঠিক আছে, সারাদিন সকালে এই নিয়ে জগাখিচুড়ি করছি। পিএইচপি মনে হচ্ছে খারাপভাবে ফর্ম্যাটেড ফাইলগুলি ফিরছে। দুটি চিত্র দেখুন , একটি অবিলম্বে রেন্ডার করা এবং অন্যটি সার্ভারে অবিলম্বে প্রতিধ্বনি a _POST এর পরে। দুটি উপাদান উপর একটি পরিবর্তন প্রকাশ করে এই যে দৃশ্যত পিএইচপি সব, "+" অক্ষর stripping করা হয়। একটি আরআর_প্লেসগুলি তাৎক্ষণিক ফেরতের জন্য এটি ঠিক করে দেয় তবে সংরক্ষণ করা ফাইলটি এখনও দুর্নীতিগ্রস্থ এবং আমার ফাইল সিস্টেমের মাধ্যমে খোলা যায় না। এছাড়াও, এগিয়ে গিয়ে এটিকে সঠিক হিসাবে চিহ্নিত করা। এখন পর্যন্ত আপনার সহায়তার জন্য অনেক ধন্যবাদ।
জোশুয়া কোডি

6

JQuery এর সাথে (এবং ফর্মডাটা এপিআই ছাড়াই) আপনি এরকম কিছু ব্যবহার করতে পারেন:

function readFile(file){
   var loader = new FileReader();
   var def = $.Deferred(), promise = def.promise();

   //--- provide classic deferred interface
   loader.onload = function (e) { def.resolve(e.target.result); };
   loader.onprogress = loader.onloadstart = function (e) { def.notify(e); };
   loader.onerror = loader.onabort = function (e) { def.reject(e); };
   promise.abort = function () { return loader.abort.apply(loader, arguments); };

   loader.readAsBinaryString(file);

   return promise;
}

function upload(url, data){
    var def = $.Deferred(), promise = def.promise();
    var mul = buildMultipart(data);
    var req = $.ajax({
        url: url,
        data: mul.data,
        processData: false,
        type: "post",
        async: true,
        contentType: "multipart/form-data; boundary="+mul.bound,
        xhr: function() {
            var xhr = jQuery.ajaxSettings.xhr();
            if (xhr.upload) {

                xhr.upload.addEventListener('progress', function(event) {
                    var percent = 0;
                    var position = event.loaded || event.position; /*event.position is deprecated*/
                    var total = event.total;
                    if (event.lengthComputable) {
                        percent = Math.ceil(position / total * 100);
                        def.notify(percent);
                    }                    
                }, false);
            }
            return xhr;
        }
    });
    req.done(function(){ def.resolve.apply(def, arguments); })
       .fail(function(){ def.reject.apply(def, arguments); });

    promise.abort = function(){ return req.abort.apply(req, arguments); }

    return promise;
}

var buildMultipart = function(data){
    var key, crunks = [], bound = false;
    while (!bound) {
        bound = $.md5 ? $.md5(new Date().valueOf()) : (new Date().valueOf());
        for (key in data) if (~data[key].indexOf(bound)) { bound = false; continue; }
    }

    for (var key = 0, l = data.length; key < l; key++){
        if (typeof(data[key].value) !== "string") {
            crunks.push("--"+bound+"\r\n"+
                "Content-Disposition: form-data; name=\""+data[key].name+"\"; filename=\""+data[key].value[1]+"\"\r\n"+
                "Content-Type: application/octet-stream\r\n"+
                "Content-Transfer-Encoding: binary\r\n\r\n"+
                data[key].value[0]);
        }else{
            crunks.push("--"+bound+"\r\n"+
                "Content-Disposition: form-data; name=\""+data[key].name+"\"\r\n\r\n"+
                data[key].value);
        }
    }

    return {
        bound: bound,
        data: crunks.join("\r\n")+"\r\n--"+bound+"--"
    };
};

//----------
//---------- On submit form:
var form = $("form");
var $file = form.find("#file");
readFile($file[0].files[0]).done(function(fileData){
   var formData = form.find(":input:not('#file')").serializeArray();
   formData.file = [fileData, $file[0].files[0].name];
   upload(form.attr("action"), formData).done(function(){ alert("successfully uploaded!"); });
});

ফর্মডাটা এপিআই দিয়ে আপনাকে আপনার ফর্মের সমস্ত ক্ষেত্রকে ফর্মডেটা অবজেক্টে যুক্ত করতে হবে এবং এটি aj .জ্যাক্সের মাধ্যমে প্রেরণ করতে হবে ({url: url, ডেটা: ফর্মডাটা, প্রক্রিয়াডাটা: মিথ্যা, সামগ্রী টাইপ: মিথ্যা, টাইপ করুন: "পোস্ট"})


4
এই সমাধানটি XMLHttpRequest.send () এর মাধ্যমে ফ্যানেল করা ডেটার উপরে চাপিয়ে দেওয়া সীমাবদ্ধতার দিকে নজর দেয় না। স্ট্রিং পাস করার পরে (যেমন আপনার মাল্টিপার্ট), প্রেরণ () বাইনারি ডেটা সমর্থন করে না। এখানে আপনার মাল্টিপার্টকে একটি utf-8 স্ট্রিং হিসাবে বিবেচনা করা হবে, এবং বাইনারি ডেটা চিকিত্সা করবে যা বৈধ utf-8 নয়। আপনি কি সত্যিই FormData এড়াতে প্রয়োজন হয়, আপনি XMLHttpRequest.sendAsBinary () (ব্যবহার করতে হবে polyfill প্রাপ্তিসাধ্য দুর্ভাগ্যবশত এর অর্থ এই যে Ajax কল জন্য jQuery ব্যবহার অনেক কঠিন হয়ে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.