Ajax का उपयोग करते हुए डेटा और फ़ाइलों को एक रूप में अपलोड करना?


384

मैं डेटा और फ़ाइलों को जमा करने के लिए अपने फॉर्म के लिए jQuery और Ajax का उपयोग कर रहा हूं लेकिन मुझे यकीन नहीं है कि डेटा और फ़ाइलों को एक रूप में कैसे भेजा जाए?

मैं वर्तमान में दोनों विधियों के साथ लगभग एक ही करता हूं लेकिन जिस तरह से डेटा को किसी सरणी में इकट्ठा किया जाता है वह अलग है, डेटा का उपयोग करता है .serialize();लेकिन फ़ाइलों का उपयोग करता है= new FormData($(this)[0]);

क्या Ajax के माध्यम से फ़ाइलों और डेटा को एक रूप में अपलोड करने में सक्षम होने के लिए दोनों तरीकों को संयोजित करना संभव है?

डेटा jQuery, Ajax और html

$("form#data").submit(function(){

    var formData = $(this).serialize();

    $.ajax({
        url: window.location.pathname,
        type: 'POST',
        data: formData,
        async: false,
        success: function (data) {
            alert(data)
        },
        cache: false,
        contentType: false,
        processData: false
    });

    return false;
});

<form id="data" method="post">
    <input type="text" name="first" value="Bob" />
    <input type="text" name="middle" value="James" />
    <input type="text" name="last" value="Smith" />
    <button>Submit</button>
</form>

फ़ाइलें jQuery, Ajax और html

$("form#files").submit(function(){

    var formData = new FormData($(this)[0]);

    $.ajax({
        url: window.location.pathname,
        type: 'POST',
        data: formData,
        async: false,
        success: function (data) {
            alert(data)
        },
        cache: false,
        contentType: false,
        processData: false
    });

    return false;
});

<form id="files" method="post" enctype="multipart/form-data">
    <input name="image" type="file" />
    <button>Submit</button>
</form>

मैं उपरोक्त कैसे संयोजित कर सकता हूं ताकि मैं अजाक्स के माध्यम से एक रूप में डेटा और फाइलें भेज सकूं?

मेरा उद्देश्य अजाक्स के साथ एक पोस्ट में इस फॉर्म के सभी भेजने में सक्षम होना है, क्या यह संभव है?

<form id="datafiles" method="post" enctype="multipart/form-data">
    <input type="text" name="first" value="Bob" />
    <input type="text" name="middle" value="James" />
    <input type="text" name="last" value="Smith" />
    <input name="image" type="file" />
    <button>Submit</button>
</form>

2
FormDataदृष्टिकोण रूपों को शामिल कि जो कुछ भी आप चाहते हैं, बस फाइल अपलोड क्षेत्रों नहीं के साथ ठीक से काम करना चाहिए; हालांकि यह व्यापक रूप से समर्थित नहीं है।
लानज

@ हालांकि, जो हालांकि? क्रमबद्ध के साथ एक केवल डेटा के लिए काम करने लगता है, लेकिन दूसरा केवल फ़ाइलों के लिए काम करने लगता है?
दान

इस MDN पृष्ठ को देखते हुए , जब आप उपयोग करते हैं, तो सभी फॉर्म डेटा को प्रस्तुत किया जाना चाहिएFormData
lanzz

1
@lanzz आप सही कह रहे हैं, यह काम करता है कि मुझे लगा कि यह होना चाहिए कि मैं गलत फॉर्म आईडी का उपयोग कर रहा था, आप एकैक्स के माध्यम से एक फॉर्म के माध्यम से फाइल और डेटा दोनों को अपलोड कर सकते हैं।
Dan

बहु-चयन फ़ाइल इनपुट होने पर यह काम नहीं करता है। यह केवल पहली फाइल अपलोड करता है।
सामी अल-सुबी

जवाबों:


458

मेरे पास जो समस्या थी वह गलत jQuery पहचानकर्ता का उपयोग कर रही थी।

आप ajax का उपयोग करके डेटा और फ़ाइलों को एक प्रपत्र के साथ अपलोड कर सकते हैं

PHP + HTML

<?php

print_r($_POST);
print_r($_FILES);
?>

<form id="data" method="post" enctype="multipart/form-data">
    <input type="text" name="first" value="Bob" />
    <input type="text" name="middle" value="James" />
    <input type="text" name="last" value="Smith" />
    <input name="image" type="file" />
    <button>Submit</button>
</form>

jQuery + अजाक्स

$("form#data").submit(function(e) {
    e.preventDefault();    
    var formData = new FormData(this);

    $.ajax({
        url: window.location.pathname,
        type: 'POST',
        data: formData,
        success: function (data) {
            alert(data)
        },
        cache: false,
        contentType: false,
        processData: false
    });
});

लघु संस्करण

$("form#data").submit(function(e) {
    e.preventDefault();
    var formData = new FormData(this);    

    $.post($(this).attr("action"), formData, function(data) {
        alert(data);
    });
});

17
IE <10 के संस्करणों में यह समाधान काम नहीं करेगा, क्योंकि FormData एक HTML5 ऑब्जेक्ट है, IE 8 या 9 में मौजूद नहीं है
जेवियर गुज़मैन

34
$(this)[0]का एक उपनाम है this, इसलिए new FormData(this)पर्याप्त होना चाहिए।
r3wt

9
यह फ़ॉर्मडाटा ऑब्जेक्ट का निरीक्षण करने के लिए संभव नहीं लगता है, इस प्रश्न को देखें (किसी के लिए भी उसी उधेड़बुन में चल रहे हैं जैसा मैंने अभी किया था क्योंकि ऑब्जेक्ट हमेशा खाली था)।
लौरा

28
भविष्य के पाठकों के लिए: contentType और processData घोषणाएँ महत्वपूर्ण हैं। अधिक जानकारी के लिए यह उत्तर देखें ।
एरोनसीब

5
यह async: falseकाम करने के लिए आवश्यक नहीं लगता है और मोबाइल (एकल थ्रेडेड) ब्राउज़रों पर अवरोध उत्पन्न करने का कारण बनता है
जेरेमी डैलर

33

एक अन्य विकल्प एक आइफ्रेम का उपयोग करना है और इसके लिए फॉर्म का लक्ष्य निर्धारित करना है।

आप यह कोशिश कर सकते हैं (यह jQuery का उपयोग करता है):

function ajax_form($form, on_complete)
{
    var iframe;

    if (!$form.attr('target'))
    {
        //create a unique iframe for the form
        iframe = $("<iframe></iframe>").attr('name', 'ajax_form_' + Math.floor(Math.random() * 999999)).hide().appendTo($('body'));
        $form.attr('target', iframe.attr('name'));
    }

    if (on_complete)
    {
        iframe = iframe || $('iframe[name="' + $form.attr('target') + '"]');
        iframe.load(function ()
        {
            //get the server response
            var response = iframe.contents().find('body').text();
            on_complete(response);
        });
    }
}

यह सभी ब्राउज़रों के साथ अच्छा काम करता है, आपको डेटा को क्रमबद्ध या तैयार करने की आवश्यकता नहीं है। एक पक्ष यह है कि आप प्रगति की निगरानी नहीं कर सकते।

कम से कम, क्रोम के लिए, अनुरोध डेवलपर टूल के "xhr" टैब में नहीं बल्कि "doc" के तहत दिखाई देगा


1
वास्तव में यह अजाक्स नहीं है, फिर भी एक ही प्रश्न वाले लोगों के लिए उपयोगी हो सकता है।
Roey

3
मैं बस विश्वास नहीं कर सकता कि यह उत्तर -2 क्यों मिलता है, मैंने इसका उपयोग करना समाप्त कर दिया क्योंकि मुझे विरासत ब्राउज़र समर्थन की आवश्यकता थी
सिज़व जूल

यह उत्तर थ्रेड में होना चाहिए क्योंकि अन्य उत्तर नोट्स 'पुराने ब्राउज़र काम नहीं करते हैं' या 'iframe hack का उपयोग किया जा सकता है' लेकिन कभी भी उन्हें संबोधित नहीं करता है। कोड का अच्छा टुकड़ा, यह भी दिखा रहा है कि
ऑनलोड को

18

मैं ASP.Net MVC में HttpPostedFilebase के साथ यही मुद्दा रख रहा था और सबमिट करने के बजाय मुझे बटन पर क्लिक करने के लिए बटन का उपयोग करने की आवश्यकता थी, जहाँ मुझे कुछ सामान करने की आवश्यकता थी और यदि सभी को सबमिट करने के लिए फॉर्म ठीक है, तो यहाँ यह कैसे काम कर रहा है?

$(".submitbtn").on("click", function(e) {

    var form = $("#Form");

    // you can't pass Jquery form it has to be javascript form object
    var formData = new FormData(form[0]);

    //if you only need to upload files then 
    //Grab the File upload control and append each file manually to FormData
    //var files = form.find("#fileupload")[0].files;

    //$.each(files, function() {
    //  var file = $(this);
    //  formData.append(file[0].name, file[0]);
    //});

    if ($(form).valid()) {
        $.ajax({
            type: "POST",
            url: $(form).prop("action"),
            //dataType: 'json', //not sure but works for me without this
            data: formData,
            contentType: false, //this is requireded please see answers above
            processData: false, //this is requireded please see answers above
            //cache: false, //not sure but works for me without this
            error   : ErrorHandler,
            success : successHandler
        });
    }
});

यह आपके MVC मॉडल को सही ढंग से आबाद करने की तुलना में, कृपया अपने मॉडल में सुनिश्चित करें, HttpPostedFileBase के लिए संपत्ति [] HTML में इनपुट नियंत्रण के नाम के समान नाम है

<input id="fileupload" type="file" name="UploadedFiles" multiple>

public class MyViewModel
{
    public HttpPostedFileBase[] UploadedFiles { get; set; }
}

1
आप एक समय बचाने वाले हैं। :)
सुहैल मुमताज़ अवन

मेरे मामले में मुझे उपयोग करना था:contentType : "application/octet-stream"
क्रिस्टोफ़ रूसो

धन्यवाद दोस्त! आपने बहुत समय बचाया।
प्रवेश निषेध

यह Django के साथ काम करता है, अच्छा!
csandreas1

धन्यवाद दोस्त! नीचे की 2 पंक्तियों ने मेरे लिए काम किया। var फॉर्म = $ ("# फॉर्म"); var formData = new FormData (फ़ॉर्म [0]);
राजीव कुमार

15

या कम:

$("form#data").submit(function() {
    var formData = new FormData(this);
    $.post($(this).attr("action"), formData, function() {
        // success    
    });
    return false;
});

तो इसी के साथ, आप उसी स्क्रिप्ट का उपयोग करके किसी डेटा फ़ील्ड को कैसे मान्य करते हैं, यदि आपके पास एक पाठ फ़ील्ड और आपके फॉर्म में एक फ़ाइल फ़ील्ड है
जॉर्ज

6

मेरे लिए, यह enctype: 'multipart/form-data'अजाक्स अनुरोध में क्षेत्र के बिना काम नहीं किया । मुझे आशा है कि यह किसी ऐसे व्यक्ति की मदद करता है जो एक समान समस्या में फंस गया है।

हालाँकि, enctype पहले से ही फॉर्म विशेषता में सेट किया गया था , किसी कारण से, अजाक्स अनुरोध स्वचालित रूप से enctypeस्पष्ट घोषणा के बिना पहचान नहीं किया गया था (jQuery 3.3.2)।

// Tested, this works for me (jQuery 3.3.1)

fileUploadForm.submit(function (e) {   
    e.preventDefault();
    $.ajax({
            type: 'POST',
            url: $(this).attr('action'),
            enctype: 'multipart/form-data',
            data: new FormData(this),
            processData: false,
            contentType: false,
            success: function (data) {
                console.log('Thank God it worked!');
            }
        }
    );
});

// enctype field was set in the form but Ajax request didn't set it by default.

<form action="process/file-upload" enctype="multipart/form-data" method="post" >

     <input type="file" name="input-file" accept="text/plain" required> 
     ...
</form>

जैसा कि दूसरों ने ऊपर बताया है, कृपया खेतों contentTypeऔर processDataक्षेत्रों पर भी विशेष ध्यान दें ।


1
"मेरे लिए, यह एंक्टाइप के बिना काम नहीं करता था: अजाक्स अनुरोध में 'मल्टीपार्ट / फॉर्म-डेटा' फ़ील्ड।" - इसका कोई असर नहीं हो सकता था। यह jQuery.ajax द्वारा मान्यता प्राप्त संपत्ति नहीं है। वह दस्तावेज देखें जहाँ enctypeउल्लेख नहीं किया गया है।
क्वेंटिन

जैसा कि मैंने पहले उल्लेख किया है, मैंने कई अलग-अलग उत्तरों की कोशिश की लेकिन वे काम करने में विफल रहे। जेएस कंसोल में एन्कोडिंग त्रुटि बताते हुए अजाक्स त्रुटि दिखाई गई। बाद में मैंने इस ट्यूटोरियल का अनुसरण किया जिससे अंत में मेरा कोड काम हो गया और मैंने इसे यहाँ पोस्ट किया। शायद, enctypeकिसी कारण से दस्तावेज़ में फ़ील्ड को कवर नहीं किया गया है। मैंने jQuery स्रोत कोड की जाँच नहीं की है इसलिए मैं निश्चितता के साथ नहीं कह सकता।
आदित्य उपाध्याय

"शायद, एक कारण के लिए दस्तावेज़ में एनक्टाइप फ़ील्ड को कवर नहीं किया गया है।" - यही कारण है कि jQuery इसके साथ कुछ भी नहीं करता है इसलिए यह बकवास है।
क्वेंटिन

शायद आप कर सकते थे मिकॉन्ग से संपर्क और उसके बजाय उससे बातचीत । मैंने enctypeक्षेत्र को हटाकर अपने कोड का फिर से परीक्षण किया और यह अब फाइल (एन्कोडिंग प्रकार त्रुटि रिटर्न) को अपलोड नहीं करता है। मुझे यकीन नहीं है कि मैं jQuery स्रोत कोड की जाँच नहीं की है कि कैसे काम करता है। मैंने यह जवाब दूसरों की मदद करने के इरादे से पोस्ट किया है जो इसी तरह की समस्या में फंसे हुए हैं। मैं यहाँ upvotes के लिए मछली पकड़ने नहीं जा रहा हूँ ... यदि आपके पास और प्रश्न / टिप्पणियाँ हैं, तो टिप्पणी करने के बजाय चैट करें।
आदित्य उपाध्याय

1

मेरे लिए कोड काम के बाद

$(function () {
    debugger;
    document.getElementById("FormId").addEventListener("submit", function (e) {
        debugger;
        if (ValidDateFrom()) { // Check Validation 
            var form = e.target;
            if (form.getAttribute("enctype") === "multipart/form-data") {
                debugger;
                if (form.dataset.ajax) {
                    e.preventDefault();
                    e.stopImmediatePropagation();
                    var xhr = new XMLHttpRequest();
                    xhr.open(form.method, form.action);
                    xhr.onreadystatechange = function (result) {
                        debugger;
                        if (xhr.readyState == 4 && xhr.status == 200) {
                            debugger;
                            var responseData = JSON.parse(xhr.responseText);
                            SuccessMethod(responseData); // Redirect to your Success method 
                        }
                    };
                    xhr.send(new FormData(form));
                }
            }
        }
    }, true);
});

अपने एक्शन पोस्ट विधि में, HttpPostedFileBase UploadFile के रूप में पैरामीटर पास करें और सुनिश्चित करें कि आपके फ़ाइल इनपुट में एक्शन विधि के पैरामीटर के अनुसार उल्लेख किया गया है। यह AJAX आरंभ फॉर्म के साथ भी काम करना चाहिए।

यहाँ पर याद रखें कि आपका AJAX BEGIN फॉर्म यहाँ पर काम नहीं करेगा क्योंकि आप ऊपर बताए गए कोड में अपनी पोस्ट कॉल को परिभाषित करते हैं और आप अपनी विधि को आवश्यकता के अनुसार कोड में संदर्भित कर सकते हैं

मुझे पता है कि मैं देर से जवाब दे रहा हूं लेकिन यह मेरे लिए काम कर रहा है


1

एक सरल लेकिन अधिक प्रभावी तरीका:
new FormData()स्वयं एक कंटेनर (या एक बैग) की तरह है। आप सब कुछ attr या फ़ाइल अपने आप में रख सकते हैं। केवल एक चीज जो आपको attribute, file, fileNameउदाहरण के लिए संलग्न करनी होगी :

let formData = new FormData()
formData.append('input', input.files[0], input.files[0].name)

और अभी इसे AJAX अनुरोध में पास करें। उदाहरण के लिए:

    let formData = new FormData()
    var d = $('#fileid')[0].files[0]

    formData.append('fileid', d);
    formData.append('inputname', value);

    $.ajax({
        url: '/yourroute',
        method: 'POST',
        contentType: false,
        processData: false,
        data: formData,
        success: function(res){
            console.log('successfully')
        },
        error: function(){
            console.log('error')
        }
    })

आप FormData के साथ एन या फ़ाइलों की संख्या को जोड़ सकते हैं।

और यदि आप Script.js फ़ाइल से AJAX के अनुरोध को Node.js में रूट फ़ाइल में कर
req.bodyरहे हैं
req.files, तो फ़ाइल (यानी छवि, वीडियो आदि) तक पहुँचने के लिए डेटा (यानी पाठ) का उपयोग करने से सावधान रहें।


-1

मेरे मामले में मुझे एक POST अनुरोध करना था, जिसमें हेडर के माध्यम से भेजी गई जानकारी थी, और फॉर्मडाटा ऑब्जेक्ट का उपयोग करके भेजी गई फ़ाइल भी थी।

मैंने यहाँ कुछ उत्तरों के संयोजन का उपयोग करके इसे बनाया है, इसलिए मूल रूप से जो काम खत्म हो रहा है वह मेरे अजाक्स अनुरोध में यह पाँच लाइनें थीं:

 contentType: "application/octet-stream",
 enctype: 'multipart/form-data',
 contentType: false,
 processData: false,
 data: formData,

फॉर्मडाटा इस तरह बनाया गया एक चर था:

 var file = document.getElementById('uploadedFile').files[0];
 var form = $('form')[0];
 var formData = new FormData(form);
 formData.append("File", file);

1
contentType: "application/octet-stream",सक्रिय रूप से हानिकारक है और एकमात्र कारण यह एक समस्या का कारण नहीं है क्योंकि आप इसे दो लाइनों को बाद में अधिलेखित कर देते हैं।
क्वेंटिन

1
enctype: 'multipart/form-data',व्यर्थ है। jQuery.ajax उस पैरामेटर को नहीं पहचानता है।
क्वेंटिन

... आपका जवाब के बाकी "डेटा की" डाटा "बिट को कवर करने में विफल रहता है और सवाल शीर्षक से फाइल"।
क्वेंटिन

-2
<form id="form" method="post" action="otherpage.php" enctype="multipart/form-data">
    <input type="text" name="first" value="Bob" />
    <input type="text" name="middle" value="James" />
    <input type="text" name="last" value="Smith" />
    <input name="image" type="file" />
    <button type='button' id='submit_btn'>Submit</button>
</form>

<script>
$(document).on("click", "#submit_btn", function (e) {
    //Prevent Instant Click  
    e.preventDefault();
    // Create an FormData object 
    var formData = $("#form").submit(function (e) {
        return;
    });
    //formData[0] contain form data only 
    // You can directly make object via using form id but it require all ajax operation inside $("form").submit(<!-- Ajax Here   -->)
    var formData = new FormData(formData[0]);
    $.ajax({
        url: $('#form').attr('action'),
        type: 'POST',
        data: formData,
        success: function (response) {
            console.log(response);
        },
        contentType: false,
        processData: false,
        cache: false
    });
    return false;
});
</script>

///// otherpage.php

<?php
    print_r($_FILES);
?>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.