Przesyłanie danych i plików w jednej formie za pomocą Ajax?

Używam jQuery i Ajax dla moich formularzy do przesyłania danych i plików, ale nie jestem pewien, jak wysłać zarówno dane, jak i pliki w jednej formie?

Obecnie robię prawie to samo z obiema metodami, ale sposób, w jaki dane są gromadzone w tablicy jest inny, dane używają .serialize();, ale pliki używają = new FormData($(this)[0]);

Czy możliwe jest połączenie obu metod, aby móc przesyłać pliki i dane w jednej formie poprzez Ajax?

Danych jQuery, Ajax i 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>

Pliki jQuery, Ajax i 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>

Jak połączyć powyższe tak, że mogę wysyłać dane i pliki w jednej formie przez Ajax?

Moim celem jest możliwość wysłania całego formularza w jednym poście z Ajaxem, czy to możliwe?

<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>
Author: mikemaccana, 2012-06-05

10 answers

Problem polegał na użyciu błędnego identyfikatora jQuery.

Możesz przesyłać dane i pliki za pomocą jednego formularza za pomocą 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 + Ajax

$("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
    });
});

Wersja Skrócona

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

    $.post($(this).attr("action"), formData, function(data) {
        alert(data);
    });
});
 484
Author: Dan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-27 18:08:51

Inną opcją jest użycie ramki iframe i ustawienie na niej celu formularza.

Możesz spróbować tego (używa 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);
        });
    }
}

Działa dobrze ze wszystkimi przeglądarkami, nie musisz serializować ani przygotowywać danych. jedną z wad jest to, że nie możesz monitorować postępów.

Również, przynajmniej dla chrome, żądanie nie pojawi się w zakładce " xhr "w narzędziach programistycznych, ale w" doc "

 34
Author: Roey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-16 08:19:18

Miałem ten sam problem w ASP.Net MVC z HttpPostedFilebase i zamiast używać formularza Na przesłać musiałem użyć przycisku na Kliknij, gdzie musiałem zrobić kilka rzeczy, a następnie, jeśli Wszystko OK, wyślij formularz tak oto, jak mam to działa

$(".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
        });
    }
});

To poprawnie wypełni twój model MVC, upewnij się, że w Twoim modelu właściwość HttpPostedFileBase[] ma taką samą nazwę jak nazwa Nazwa kontrolki wejściowej w html, tj.

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

public class MyViewModel
{
    public HttpPostedFileBase[] UploadedFiles { get; set; }
}
 19
Author: h_power11,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-04 16:20:53

Lub krótszy:

$("form#data").submit(function() {
    var formData = new FormData(this);
    $.post($(this).attr("action"), formData, function() {
        // success    
    });
    return false;
});
 17
Author: schaenk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-11 13:06:11

Dla mnie nie działało bez pola enctype: 'multipart/form-data' w żądaniu Ajax. Mam nadzieję, że pomoże to komuś, kto utknął w podobnym problemie.

/ Align = "left" / enctype był już ustawiony w atrybucie formularza , z jakiegoś powodu żądanie Ajax nie zidentyfikowało automatycznie enctype bez wyraźnej deklaracji (jQuery 3.3.1).
// 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>

Podobnie jak inne wymienione powyżej, należy zwrócić szczególną uwagę na pola contentType i processData.

 12
Author: Adithya Upadhya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-06 01:29:48

Dla mnie po pracy kodu

$(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);
});

W metodzie Action Post przekaż parametr jako plik UploadFile HttpPostedFileBase i upewnij się, że dane wejściowe pliku są takie same, jak wymienione w parametrze metody akcji. Powinno działać również z AJAX Begin form.

Pamiętaj tutaj, że twój formularz Ajax BEGIN nie będzie działał tutaj, ponieważ wykonujesz wywołanie Post zdefiniowane w kodzie wymienionym powyżej i możesz odwołać się do swojej metody w kodzie zgodnie z wymogiem

I wiem, że odpowiadam późno, ale to dla mnie zadziałało

 1
Author: Pranav Kulshrestha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-15 21:20:57

Prosty, ale bardziej skuteczny sposób:
new FormData() sam w sobie jest jak pojemnik (lub torba). Możesz umieścić wszystko attr lub plik w sobie. Jedyne co musisz dodać attribute, file, fileName np:

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

I po prostu podaj go w żądaniu AJAX. Eg:

    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')
        }
    })

Możesz dodać n liczby plików lub danych za pomocą FormData.

I jeśli tworzysz żądanie AJAX ze skryptu.plik js do pliku trasy w węźle.js beware of using
req.body Aby uzyskać dostęp do danych (tj. tekst)
req.files aby uzyskać dostęp do pliku (ie image, video etc)

 1
Author: kartik tyagi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-05 06:15:46

Możesz po prostu dołączyć je do swoich formdata, dodać do nich swoje pliki i dane.możesz to przeczytać..

Https://developer.mozilla.org/en-US/docs/Web/API/FormData/append

Dla lepszego zrozumienia. można je oddzielnie pobrać $_FILES dla plików i $_POST dla danych.

 0
Author: ryuhk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-12 13:44:31

W moim przypadku musiałem wykonać żądanie POST, które zawierało informacje wysyłane przez nagłówek, a także plik wysyłany za pomocą obiektu FormData.

Sprawiłem, że to działało, używając kombinacji niektórych odpowiedzi tutaj, więc w zasadzie to, co skończyło się pracą, to posiadanie tych pięciu linijek w moim żądaniu Ajax:

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

Gdzie formData była zmienną utworzoną w ten sposób:

 var file = document.getElementById('uploadedFile').files[0];
 var form = $('form')[0];
 var formData = new FormData(form);
 formData.append("File", file);
 -1
Author: ndarriulat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-01 11:05:42
<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);
?>
 -3
Author: Shailesh Dwivedi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-15 18:13:57