jQuery Ajax File Upload

755

Czy mogę użyć następującego kodu jQuery do przesłania pliku przy użyciu metody POST żądania ajax?

$.ajax({
    type: "POST",
    timeout: 50000,
    url: url,
    data: dataString,
    success: function (data) {
        alert('success');
        return false;
    }
});

Jeśli to możliwe, czy muszę wypełnić dataczęść? Czy to właściwy sposób? Wysyłam plik tylko po stronie serwera.

Gogłem się w kółko, ale znalazłem wtyczkę, ale w swoim planie nie chcę jej używać. Przynajmniej na razie.

Willy
źródło
Ajax nie obsługuje przesyłania plików, zamiast tego należy użyć iframe
antyrat
1
Powiązane pytanie: stackoverflow.com/questions/6974684/…
Nathan Koop
2
Powiązane: stackoverflow.com/questions/166221/…
Timo Huovinen

Odpowiedzi:

596

Przesyłanie pliku nie jest możliwe za pośrednictwem AJAX.
Możesz przesłać plik bez odświeżania strony za pomocą IFrame.
Możesz sprawdzić dalsze szczegóły tutaj .


AKTUALIZACJA

W XHR2 obsługiwane jest przesyłanie plików przez AJAX. Np. Przez FormDataobiekt, ale niestety nie jest obsługiwany przez wszystkie / stare przeglądarki.

FormData Wsparcie zaczyna się od następujących wersji przeglądarek na komputery.

  • IE 10+
  • Firefox 4.0+
  • Chrome 7+
  • Safari 5+
  • Opera 12+

Aby uzyskać więcej informacji, zobacz łącze MDN .

Adeel
źródło
41
Oto lista konkretnych przeglądarek, które nie są obsługiwane: caniuse.com/#search=FormData Również tego nie testowałem, ale tutaj jest polifill dla FormData gist.github.com/3120320
Ryan White
152
W szczególności IE <10 nie, dla osób zbyt leniwych, aby przeczytać link.
Kevin
22
@Synexis nie, nie musimy już tak długo czekać, ponieważ wszystkie IE ma tylko 22% udział w rynku światowym i 27% w Stanach Zjednoczonych i szybko spada. Są szanse, że to ludzie powyżej 70 lat. Zamiast tego IE dyktując, co muszą zrobić programiści, IE będzie musiało się ukształtować lub wyjść z wyścigu.
Drew Calder
30
@DrewCalder Większość użytkowników IE to pracownicy biurowi, którzy nie mają możliwości wyboru przeglądarki, z powodu zasad firmy. Nie sądzę, żeby wiek miał z tym wiele wspólnego. Domyślam się, że większość osób w wieku> 70 lat dostaje swoje potomstwo, by zamiast tego zainstalować Chrome lub FF :)
Nicolas Connault,
3
Ten link naprawdę pomógł mi zrozumieć absolutne minimum. Nie musiałem używać żądania xhr. Jeśli używasz ajax, ustaw opcję enctypena "form/multipart"!
Luminous
316

Ramki iframe nie są już potrzebne do przesyłania plików przez ajax. Ostatnio zrobiłem to sam. Sprawdź te strony:

Korzystanie z przesyłania plików HTML5 z AJAX i jQuery

http://dev.w3.org/2006/webapi/FileAPI/#FileReader-interface

Zaktualizowałem odpowiedź i wyczyściłem ją. Użyj funkcji getSize, aby sprawdzić rozmiar, lub użyj funkcji getType, aby sprawdzić typy. Dodano kod HTML i css paska postępu.

var Upload = function (file) {
    this.file = file;
};

Upload.prototype.getType = function() {
    return this.file.type;
};
Upload.prototype.getSize = function() {
    return this.file.size;
};
Upload.prototype.getName = function() {
    return this.file.name;
};
Upload.prototype.doUpload = function () {
    var that = this;
    var formData = new FormData();

    // add assoc key values, this will be posts values
    formData.append("file", this.file, this.getName());
    formData.append("upload_file", true);

    $.ajax({
        type: "POST",
        url: "script",
        xhr: function () {
            var myXhr = $.ajaxSettings.xhr();
            if (myXhr.upload) {
                myXhr.upload.addEventListener('progress', that.progressHandling, false);
            }
            return myXhr;
        },
        success: function (data) {
            // your callback here
        },
        error: function (error) {
            // handle error
        },
        async: true,
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        timeout: 60000
    });
};

Upload.prototype.progressHandling = function (event) {
    var percent = 0;
    var position = event.loaded || event.position;
    var total = event.total;
    var progress_bar_id = "#progress-wrp";
    if (event.lengthComputable) {
        percent = Math.ceil(position / total * 100);
    }
    // update progressbars classes so it fits your code
    $(progress_bar_id + " .progress-bar").css("width", +percent + "%");
    $(progress_bar_id + " .status").text(percent + "%");
};

Jak korzystać z klasy Upload

//Change id to your id
$("#ingredient_file").on("change", function (e) {
    var file = $(this)[0].files[0];
    var upload = new Upload(file);

    // maby check size or type here with upload.getSize() and upload.getType()

    // execute upload
    upload.doUpload();
});

Kod HTML paska postępu

<div id="progress-wrp">
    <div class="progress-bar"></div>
    <div class="status">0%</div>
</div>

Kod css paska postępu

#progress-wrp {
  border: 1px solid #0099CC;
  padding: 1px;
  position: relative;
  height: 30px;
  border-radius: 3px;
  margin: 10px;
  text-align: left;
  background: #fff;
  box-shadow: inset 1px 3px 6px rgba(0, 0, 0, 0.12);
}

#progress-wrp .progress-bar {
  height: 100%;
  border-radius: 3px;
  background-color: #f39ac7;
  width: 0;
  box-shadow: inset 1px 1px 10px rgba(0, 0, 0, 0.11);
}

#progress-wrp .status {
  top: 3px;
  left: 50%;
  position: absolute;
  display: inline-block;
  color: #000000;
}
Ziinloader
źródło
3
Możesz mniej więcej skopiować kod i użyć go. Wystarczy zmienić niektóre identyfikatory i nazwy klas. Wszelkie dostosowania są na własną rękę.
Ziinloader
4
Zauważ, że myXhr wydaje się być globalny, a także nazwa, rozmiar i typ. Lepiej jest także użyć „beforeSend”, aby rozszerzyć już utworzony obiekt XMLHttpRequest, zamiast używać „xhr”, aby go utworzyć, a następnie zmienić.
awatts
8
Nie sądzę, że możemy tego użyć tak jak @ Ziinloader. Używasz jakiegoś lokalnego sposób, że nie było: writer(catchFile). Co to jest writer()?
tandrewnichols
4
Co jeśli dane zawierają również kilka pól wraz z plikiem do przesłania?
raju
2
@ Ziinloader Jest to niezwykle przydatny przykład, w którym widzę, że wróciłeś i utrzymywałeś go kilka razy. Naprawdę odpowiedź warta znacznie więcej niż jedna opinia, którą mogę udzielić.
Zwykły Joe
190

Możliwe jest przesyłanie i przesyłanie pliku Ajax. Używam jQuery $.ajaxfunkcji do ładowania plików. Próbowałem użyć obiektu XHR, ale nie mogłem uzyskać wyników po stronie serwera za pomocą PHP.

var formData = new FormData();
formData.append('file', $('#file')[0].files[0]);

$.ajax({
       url : 'upload.php',
       type : 'POST',
       data : formData,
       processData: false,  // tell jQuery not to process the data
       contentType: false,  // tell jQuery not to set contentType
       success : function(data) {
           console.log(data);
           alert(data);
       }
});

Jak widać, należy utworzyć obiekt FormData, pusty lub z (zserializowany? - $('#yourForm').serialize())istniejący formularz, a następnie dołączyć plik wejściowy.

Oto więcej informacji: - Jak przesłać plik przy użyciu jQuery.ajax i FormData - Przesyłanie plików przez jQuery, obiekt FormData jest podany i nie ma nazwy pliku, żądanie GET

Do procesu PHP możesz użyć czegoś takiego:

//print_r($_FILES);
$fileName = $_FILES['file']['name'];
$fileType = $_FILES['file']['type'];
$fileError = $_FILES['file']['error'];
$fileContent = file_get_contents($_FILES['file']['tmp_name']);

if($fileError == UPLOAD_ERR_OK){
   //Processes your file here
}else{
   switch($fileError){
     case UPLOAD_ERR_INI_SIZE:   
          $message = 'Error al intentar subir un archivo que excede el tamaño permitido.';
          break;
     case UPLOAD_ERR_FORM_SIZE:  
          $message = 'Error al intentar subir un archivo que excede el tamaño permitido.';
          break;
     case UPLOAD_ERR_PARTIAL:    
          $message = 'Error: no terminó la acción de subir el archivo.';
          break;
     case UPLOAD_ERR_NO_FILE:    
          $message = 'Error: ningún archivo fue subido.';
          break;
     case UPLOAD_ERR_NO_TMP_DIR: 
          $message = 'Error: servidor no configurado para carga de archivos.';
          break;
     case UPLOAD_ERR_CANT_WRITE: 
          $message= 'Error: posible falla al grabar el archivo.';
          break;
     case  UPLOAD_ERR_EXTENSION: 
          $message = 'Error: carga de archivo no completada.';
          break;
     default: $message = 'Error: carga de archivo no completada.';
              break;
    }
      echo json_encode(array(
               'error' => true,
               'message' => $message
            ));
}
pedrozopayares
źródło
2
Do jakiej biblioteki jquery muszę się odwoływać, aby uruchomić ten kod?
Rayden Black,
Odpowiedź została napisana w 2014 roku. Wersja JQuery miała wersję 1.10. Nie próbowałem z nowszymi wersjami.
pedrozopayares
5
formData.append('file', $('#file')[0].files[0]);zwraca undefinedi console.log(formData) nie ma nic oprócz_proto_
Yakob Ubaidi
1
Nie obsługiwany przez IE 9, na wypadek, gdyby niektóre utknęły w tym samym piekle co ja
CountMurphy
3
Mam to do pracy ... Uszczypnij mnie, jestem na niebie przesyłania plików jQuery Ajax! var formData = new FormData(); formData.append('file', document.getElementById('file').files[0]); $.ajax({ url : $("form[name='uploadPhoto']").attr("action"), type : 'POST', data : formData, processData: false, // tell jQuery not to process the data contentType: false, // tell jQuery not to set contentType success : function(data) { console.log(data); alert(data); } });
TARKUS
104

Prosty formularz przesyłania

 <script>
   //form Submit
   $("form").submit(function(evt){	 
      evt.preventDefault();
      var formData = new FormData($(this)[0]);
   $.ajax({
       url: 'fileUpload',
       type: 'POST',
       data: formData,
       async: false,
       cache: false,
       contentType: false,
       enctype: 'multipart/form-data',
       processData: false,
       success: function (response) {
         alert(response);
       }
   });
   return false;
 });
</script>
<!--Upload Form-->
<form>
  <table>
    <tr>
      <td colspan="2">File Upload</td>
    </tr>
    <tr>
      <th>Select File </th>
      <td><input id="csv" name="csv" type="file" /></td>
    </tr>
    <tr>
      <td colspan="2">
        <input type="submit" value="submit"/> 
      </td>
    </tr>
  </table>
</form>

vickisys
źródło
proszę pana, jakie są pliki js, które zostały użyte w tym przykładzie, czy istnieje konkretna wtyczka jquery dla tego .. Mam pytanie, które zostało wskazane tutaj, proszę sprawdź moje pytanie .. Chcę załadować wiele plików lub obrazów w tym projekcie tutaj to link stackoverflow.com/questions/28644200/...
Brownman Revival
19
$ (this) [0] is this
machineaddict
2
Jaki jest parametr na serwerze dla opublikowanego pliku? Czy możesz wysłać część serwera?
FrenkyB
@FrenkyB i inne - pliki na serwerze (w PHP) nie są przechowywane w zmiennej $ _POST - są przechowywane w zmiennej $ _FILES. W takim przypadku uzyskasz do niego dostęp za pomocą $ _FILES [„csv”], ponieważ „csv” jest atrybutem nazwy znacznika wejściowego.
dev_masta
68

Spóźniłem się na to, ale szukałem rozwiązania do przesyłania obrazów opartego na ajax, a odpowiedź, której szukałem, była trochę rozproszona w tym poście. Rozwiązanie, na którym się zdecydowałem, dotyczyło obiektu FormData. Złożyłem podstawową formę kodu, który skompletowałem. Możesz zobaczyć, jak pokazuje, jak dodać niestandardowe pole do formularza za pomocą fd.append (), a także jak obsługiwać dane odpowiedzi po zakończeniu żądania ajax.

Prześlij html:

<!DOCTYPE html>
<html>
<head>
    <title>Image Upload Form</title>
    <script src="//code.jquery.com/jquery-1.9.1.js"></script>
    <script type="text/javascript">
        function submitForm() {
            console.log("submit event");
            var fd = new FormData(document.getElementById("fileinfo"));
            fd.append("label", "WEBUPLOAD");
            $.ajax({
              url: "upload.php",
              type: "POST",
              data: fd,
              processData: false,  // tell jQuery not to process the data
              contentType: false   // tell jQuery not to set contentType
            }).done(function( data ) {
                console.log("PHP Output:");
                console.log( data );
            });
            return false;
        }
    </script>
</head>

<body>
    <form method="post" id="fileinfo" name="fileinfo" onsubmit="return submitForm();">
        <label>Select a file:</label><br>
        <input type="file" name="file" required />
        <input type="submit" value="Upload" />
    </form>
    <div id="output"></div>
</body>
</html>

Jeśli pracujesz z php, oto sposób obsługi przesyłania, który obejmuje wykorzystanie obu pól niestandardowych pokazanych w powyższym HTML.

Upload.php

<?php
if ($_POST["label"]) {
    $label = $_POST["label"];
}
$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp);
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 200000)
&& in_array($extension, $allowedExts)) {
    if ($_FILES["file"]["error"] > 0) {
        echo "Return Code: " . $_FILES["file"]["error"] . "<br>";
    } else {
        $filename = $label.$_FILES["file"]["name"];
        echo "Upload: " . $_FILES["file"]["name"] . "<br>";
        echo "Type: " . $_FILES["file"]["type"] . "<br>";
        echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
        echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br>";

        if (file_exists("uploads/" . $filename)) {
            echo $filename . " already exists. ";
        } else {
            move_uploaded_file($_FILES["file"]["tmp_name"],
            "uploads/" . $filename);
            echo "Stored in: " . "uploads/" . $filename;
        }
    }
} else {
    echo "Invalid file";
}
?>
lee8oi
źródło
Dostaję Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https,dlaczego jest to tak sir skopiować wkleić kod, jak to jest
Brownman Revival
2
@HogRider - jeśli wyślesz Google komunikat o błędzie, jest to pierwszy wynik: stackoverflow.com/questions/10752055/… Czy uzyskujesz dostęp do swoich stron lokalnie file://, a nie za pomocą serwera WWW? Nawiasem mówiąc, nie jest najlepszą praktyką po prostu kopiowanie i wklejanie kodu na ślepo bez uprzedniego zrozumienia. Polecam przejrzenie kodu wiersz po wierszu, aby zrozumieć, co się dzieje przed użyciem kodu.
colincameron
@colincameron dziękuję za wyjaśnienie kilku rzeczy, które przeszedłem przez linię po linii i naprawdę nie rozumiem wiele, więc zadałem pytanie, aby ktoś mógł wyjaśnić moje wątpliwości. Używam lokalnego Xamppa, żeby być dokładnym. Czy mogę zadać pytanie, które może wyjaśnić?
Brownman Revival
@Brownman Revival: Wiem, że jest już za późno na odpowiedź. Wystąpił błąd krzyżowego pochodzenia, ponieważ otworzyłeś plik HTML jako plik niż uruchamiając go z serwera.
Adarsh ​​Mohan
@AdarshMohan Doceniam odpowiedź Jak sugerujesz zrobić to, żeby było dobrze?
Brownman Revival
31

Przesyłanie AJAX jest rzeczywiście możliwe przy pomocy XMLHttpRequest(). Nie są wymagane iframe. Postęp przesyłania można wyświetlić.

Aby uzyskać szczegółowe informacje, patrz: Odpowiedz https://stackoverflow.com/a/4943774/873282, aby zakwestionować postęp przesyłania jQuery i przesyłanie pliku AJAX .

koppor
źródło
24
Niestety IE <10 nie obsługuje tego.
Sasha Chedygov,
1
Jeśli chcesz jedynie odnieść się do innej strony jako odpowiedzi, możesz głosować na zamknięcie jako dupkucate lub pozostawić komentarz pod pytaniem. Ten post nie jest odpowiedzią. Tego rodzaju post wygląda jak próba farmowania przedstawiciela.
mickmackusa
18

Oto jak to działa:

HTML

<input type="file" id="file">
<button id='process-file-button'>Process</button>

JS

$('#process-file-button').on('click', function (e) {
    let files = new FormData(), // you can consider this as 'data bag'
        url = 'yourUrl';

    files.append('fileName', $('#file')[0].files[0]); // append selected file to the bag named 'file'

    $.ajax({
        type: 'post',
        url: url,
        processData: false,
        contentType: false,
        data: files,
        success: function (response) {
            console.log(response);
        },
        error: function (err) {
            console.log(err);
        }
    });
});

PHP

if (isset($_FILES) && !empty($_FILES)) {
    $file = $_FILES['fileName'];
    $name = $file['name'];
    $path = $file['tmp_name'];


    // process your file

}
М.Б.
źródło
2
Najbardziej pomogło mi w tym $('#file')[0].files[0]dziwne obejście JS bez konieczności odpowiedniego<form>
ffgpga08
To kompletne rozwiązanie, pomaga również bit PHP.
cdsaenz
14

Jeśli chcesz to zrobić w ten sposób:

$.upload( form.action, new FormData( myForm))
.progress( function( progressEvent, upload) {
    if( progressEvent.lengthComputable) {
        var percent = Math.round( progressEvent.loaded * 100 / progressEvent.total) + '%';
        if( upload) {
            console.log( percent + ' uploaded');
        } else {
            console.log( percent + ' downloaded');
        }
    }
})
.done( function() {
    console.log( 'Finished upload');                    
});

niż

https://github.com/lgersman/jquery.orangevolt-ampere/blob/master/src/jquery.upload.js

może być twoim rozwiązaniem.

Lgersman
źródło
Gdzie jest metoda przesyłania w obiekcie $, powyższy link nie istnieje
najfajniejszy
2
Dziękujemy za opublikowanie odpowiedzi! Przeczytaj uważnie FAQ dotyczące autopromocji . Należy również pamiętać, że jest to konieczne , aby umieścić disclaimer każdym razem, gdy odwołują się do swojej własnej strony / produktu.
Andrew Barber
13
  • Użyj ukrytego elementu iframe i ustaw cel formularza na nazwę tego elementu iframe. W ten sposób po przesłaniu formularza odświeżana będzie tylko ramka iframe.
  • Poproś o zarejestrowanie procedury obsługi zdarzenia ładowania iframe w celu przeanalizowania odpowiedzi.

Więcej szczegółów na moim blogu: http://blog.manki.in/2011/08/ajax-fie-upload.html .

Manki
źródło
Unikaj ramek iframe tam, gdzie to możliwe
Bhargav Nanekalva,
@BhargavNanekalva, czym się martwisz?
aswzen
13
$("#submit_car").click( function() {
  var formData = new FormData($('#car_cost_form')[0]);
$.ajax({
       url: 'car_costs.php',
       data: formData,
       async: false,
       contentType: false,
       processData: false,
       cache: false,
       type: 'POST',
       success: function(data)
       {
       },
     })    return false;    
});

edycja: Uwaga rodzaj treści i dane procesowe Możesz tego użyć do przesłania plików przez Ajax ...... przesłanie danych wejściowych nie może być poza elementem formularza :)

Gvice
źródło
3
Za pomocą tej metody można publikować formularze, ale nie za pomocą pól typu „plik”. To pytanie dotyczy w szczególności przesyłania plików.
Jomy John,
11

Aktualizacja 2019:

HTML

<form class="fr" method='POST' enctype="multipart/form-data"> {% csrf_token %}
<textarea name='text'>
<input name='example_image'>
<button type="submit">
</form>

js

$(document).on('submit', '.fr', function(){

    $.ajax({ 
        type: 'post', 
        url: url, <--- you insert proper URL path to call your views.py function here.
        enctype: 'multipart/form-data',
        processData: false,
        contentType: false,
        data: new FormData(this) ,
        success: function(data) {
             console.log(data);
        }
        });
        return false;

    });

views.py

form = ThisForm(request.POST, request.FILES)

if form.is_valid():
    text = form.cleaned_data.get("text")
    example_image = request.FILES['example_image']
Sójka
źródło
1
W jaki sposób poprawia to którekolwiek z udzielonych już odpowiedzi? Również ta odpowiedź wspomina o pliku views.py, który jest Django i nie ma nic wspólnego z pytaniem.
dirkgroten
6
Ponieważ problem pojawia się w porównywalny sposób podczas korzystania z Django, a jeśli używasz Django, nie ma tu wiele wskazówek dotyczących jego rozwiązania. Myślałem, że zaoferuję proaktywną pomoc na wypadek, gdyby ktoś tu przybył, tak jak ja w przyszłości. Masz ciężki dzień?
Jay
9

Użyj FormData. Działa naprawdę dobrze :-) ...

var jform = new FormData();
jform.append('user',$('#user').val());
jform.append('image',$('#image').get(0).files[0]); // Here's the important bit

$.ajax({
    url: '/your-form-processing-page-url-here',
    type: 'POST',
    data: jform,
    dataType: 'json',
    mimeType: 'multipart/form-data', // this too
    contentType: false,
    cache: false,
    processData: false,
    success: function(data, status, jqXHR){
        alert('Hooray! All is well.');
        console.log(data);
        console.log(status);
        console.log(jqXHR);

    },
    error: function(jqXHR,status,error){
        // Hopefully we should never reach here
        console.log(jqXHR);
        console.log(status);
        console.log(error);
    }
});
delboy1978uk
źródło
to jest to: ('user', $ ('# user'). val ());
rahim.nagori
pole tekstowe o identyfikatorze = „użytkownik” jest dołączane do formularza @ rahim.nagori
Alp Altunel
7

Zaimplementowałem opcję wyboru wielu plików z natychmiastowym podglądem i przesyłaniem po usunięciu niechcianych plików z podglądu za pośrednictwem ajax.

Szczegółową dokumentację można znaleźć tutaj: http://anasthecoder.blogspot.ae/2014/12/multi-file-select-preview-without.html

Demo: http://jsfiddle.net/anas/6v8Kz/7/embedded/result/

jsFiddle: http://jsfiddle.net/anas/6v8Kz/7/

JavaScript:

    $(document).ready(function(){
    $('form').submit(function(ev){
        $('.overlay').show();
        $(window).scrollTop(0);
        return upload_images_selected(ev, ev.target);
    })
})
function add_new_file_uploader(addBtn) {
    var currentRow = $(addBtn).parent().parent();
    var newRow = $(currentRow).clone();
    $(newRow).find('.previewImage, .imagePreviewTable').hide();
    $(newRow).find('.removeButton').show();
    $(newRow).find('table.imagePreviewTable').find('tr').remove();
    $(newRow).find('input.multipleImageFileInput').val('');
    $(addBtn).parent().parent().parent().append(newRow);
}

function remove_file_uploader(removeBtn) {
    $(removeBtn).parent().parent().remove();
}

function show_image_preview(file_selector) {
    //files selected using current file selector
    var files = file_selector.files;
    //Container of image previews
    var imageContainer = $(file_selector).next('table.imagePreviewTable');
    //Number of images selected
    var number_of_images = files.length;
    //Build image preview row
    var imagePreviewRow = $('<tr class="imagePreviewRow_0"><td valign=top style="width: 510px;"></td>' +
        '<td valign=top><input type="button" value="X" title="Remove Image" class="removeImageButton" imageIndex="0" onclick="remove_selected_image(this)" /></td>' +
        '</tr> ');
    //Add image preview row
    $(imageContainer).html(imagePreviewRow);
    if (number_of_images > 1) {
        for (var i =1; i<number_of_images; i++) {
            /**
             *Generate class name of the respective image container appending index of selected images, 
             *sothat we can match images selected and the one which is previewed
             */
            var newImagePreviewRow = $(imagePreviewRow).clone().removeClass('imagePreviewRow_0').addClass('imagePreviewRow_'+i);
            $(newImagePreviewRow).find('input[type="button"]').attr('imageIndex', i);
            $(imageContainer).append(newImagePreviewRow);
        }
    }
    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        /**
         * Allow only images
         */
        var imageType = /image.*/;
        if (!file.type.match(imageType)) {
          continue;
        }

        /**
         * Create an image dom object dynamically
         */
        var img = document.createElement("img");

        /**
         * Get preview area of the image
         */
        var preview = $(imageContainer).find('tr.imagePreviewRow_'+i).find('td:first');

        /**
         * Append preview of selected image to the corresponding container
         */
        preview.append(img); 

        /**
         * Set style of appended preview(Can be done via css also)
         */
        preview.find('img').addClass('previewImage').css({'max-width': '500px', 'max-height': '500px'});

        /**
         * Initialize file reader
         */
        var reader = new FileReader();
        /**
         * Onload event of file reader assign target image to the preview
         */
        reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
        /**
         * Initiate read
         */
        reader.readAsDataURL(file);
    }
    /**
     * Show preview
     */
    $(imageContainer).show();
}

function remove_selected_image(close_button)
{
    /**
     * Remove this image from preview
     */
    var imageIndex = $(close_button).attr('imageindex');
    $(close_button).parents('.imagePreviewRow_' + imageIndex).remove();
}

function upload_images_selected(event, formObj)
{
    event.preventDefault();
    //Get number of images
    var imageCount = $('.previewImage').length;
    //Get all multi select inputs
    var fileInputs = document.querySelectorAll('.multipleImageFileInput');
    //Url where the image is to be uploaded
    var url= "/upload-directory/";
    //Get number of inputs
    var number_of_inputs = $(fileInputs).length; 
    var inputCount = 0;

    //Iterate through each file selector input
    $(fileInputs).each(function(index, input){

        fileList = input.files;
        // Create a new FormData object.
        var formData = new FormData();
        //Extra parameters can be added to the form data object
        formData.append('bulk_upload', '1');
        formData.append('username', $('input[name="username"]').val());
        //Iterate throug each images selected by each file selector and find if the image is present in the preview
        for (var i = 0; i < fileList.length; i++) {
            if ($(input).next('.imagePreviewTable').find('.imagePreviewRow_'+i).length != 0) {
                var file = fileList[i];
                // Check the file type.
                if (!file.type.match('image.*')) {
                    continue;
                }
                // Add the file to the request.
                formData.append('image_uploader_multiple[' +(inputCount++)+ ']', file, file.name);
            }
        }
        // Set up the request.
        var xhr = new XMLHttpRequest();
        xhr.open('POST', url, true);
        xhr.onload = function () {
            if (xhr.status === 200) {
                var jsonResponse = JSON.parse(xhr.responseText);
                if (jsonResponse.status == 1) {
                    $(jsonResponse.file_info).each(function(){
                        //Iterate through response and find data corresponding to each file uploaded
                        var uploaded_file_name = this.original;
                        var saved_file_name = this.target;
                        var file_name_input = '<input type="hidden" class="image_name" name="image_names[]" value="' +saved_file_name+ '" />';
                        file_info_container.append(file_name_input);

                        imageCount--;
                    })
                    //Decrement count of inputs to find all images selected by all multi select are uploaded
                    number_of_inputs--;
                    if(number_of_inputs == 0) {
                        //All images selected by each file selector is uploaded
                        //Do necessary acteion post upload
                        $('.overlay').hide();
                    }
                } else {
                    if (typeof jsonResponse.error_field_name != 'undefined') {
                        //Do appropriate error action
                    } else {
                        alert(jsonResponse.message);
                    }
                    $('.overlay').hide();
                    event.preventDefault();
                    return false;
                }
            } else {
                /*alert('Something went wrong!');*/
                $('.overlay').hide();
                event.preventDefault();
            }
        };
        xhr.send(formData);
    })

    return false;
}
Ima
źródło
@Bhargav: wyjaśnienia znajdują się na blogu: goo.gl/umgFFy . Jeśli nadal masz jakieś pytania, wróć do mnie Dzięki
Ima
7

Poradziłem sobie z nimi w prostym kodzie. Możesz pobrać działającą wersję demo tutaj

W twoim przypadku są to bardzo możliwe. Pokażę ci krok po kroku, jak możesz wgrać plik na serwer za pomocą jQuery AJAX.

Najpierw stwórzmy plik HTML, aby dodać następujący element pliku formularza, jak pokazano poniżej.

<form action="" id="formContent" method="post" enctype="multipart/form-data" >
         <input  type="file" name="file"  required id="upload">
         <button class="submitI" >Upload Image</button> 
</form>

Po drugie, utwórz plik jquery.js i dodaj następujący kod, aby obsłużyć nasze przesyłanie plików na serwer

    $("#formContent").submit(function(e){
        e.preventDefault();

    var formdata = new FormData(this);

        $.ajax({
            url: "ajax_upload_image.php",
            type: "POST",
            data: formdata,
            mimeTypes:"multipart/form-data",
            contentType: false,
            cache: false,
            processData: false,
            success: function(){
                alert("file successfully submitted");
            },error: function(){
                alert("okey");
            }
         });
      });
    });

Gotowe. Zobacz więcej

Daniel Nyamasyo
źródło
7

Korzystanie z FormData to droga, na którą wskazuje wiele odpowiedzi. oto trochę kodu, który działa świetnie w tym celu. Zgadzam się również z komentarzem dotyczącym zagnieżdżania bloków ajax w celu spełnienia złożonych okoliczności. Dołączając e.PreventDefault (); z mojego doświadczenia wynika, że ​​kod jest bardziej kompatybilny z różnymi przeglądarkami.

    $('#UploadB1').click(function(e){        
    e.preventDefault();

    if (!fileupload.valid()) {
        return false;            
    }

    var myformData = new FormData();        
    myformData.append('file', $('#uploadFile')[0].files[0]);

    $("#UpdateMessage5").html("Uploading file ....");
    $("#UpdateMessage5").css("background","url(../include/images/loaderIcon.gif) no-repeat right");

    myformData.append('mode', 'fileUpload');
    myformData.append('myid', $('#myid').val());
    myformData.append('type', $('#fileType').val());
    //formData.append('myfile', file, file.name); 

    $.ajax({
        url: 'include/fetch.php',
        method: 'post',
        processData: false,
        contentType: false,
        cache: false,
        data: myformData,
        enctype: 'multipart/form-data',
        success: function(response){
            $("#UpdateMessage5").html(response); //.delay(2000).hide(1); 
            $("#UpdateMessage5").css("background","");

            console.log("file successfully submitted");
        },error: function(){
            console.log("not okay");
        }
    });
});
Mike Volmar
źródło
uruchamia to formularz sprawdzania poprawności jquery ... if (! fileupload.valid ()) {return false; }
Mike Volmar,
7

Używanie czystego js jest łatwiejsze

async function saveFile(inp) 
{
    let formData = new FormData();           
    formData.append("file", inp.files[0]);
    await fetch('/upload/somedata', {method: "POST", body: formData});    
    alert('success');
}
<input type="file" onchange="saveFile(this)" >

  • Po stronie serwera możesz odczytać oryginalną nazwę pliku (i inne informacje), która jest automatycznie dołączana na żądanie.
  • NIE musisz ustawiać nagłówka „Content-Type” na „multipart / form-data”, przeglądarka ustawi go automatycznie
  • Te rozwiązania powinny działać we wszystkich głównych przeglądarkach.

Oto bardziej rozwinięty fragment kodu z obsługą błędów i dodatkowym wysyłaniem plików Json

Kamil Kiełczewski
źródło
6

Tak, możesz po prostu użyć javascript, aby uzyskać plik, upewniając się, że czytasz plik jako adres URL danych. Przetwarzaj rzeczy przed base64, aby faktycznie pobrać dane zakodowane w standardzie 64, a następnie, jeśli używasz php lub dowolnego języka zaplecza, możesz zdekodować dane w bazie 64 i zapisać w pliku, jak pokazano poniżej

Javascript:
var reader = new FileReader();
reader.onloadend = function ()
{
  dataToBeSent = reader.result.split("base64,")[1];
  $.post(url, {data:dataToBeSent});
}
reader.readAsDataURL(this.files[0]);


PHP:
    file_put_contents('my.pdf', base64_decode($_POST["data"]));

Oczywiście prawdopodobnie będziesz chciał przeprowadzić pewną weryfikację, na przykład sprawdzić, z jakim typem pliku masz do czynienia i takie tam, ale taki jest pomysł.

Piacenti
źródło
file_put_contents ($ fname, file_get_contents ($ _ POST ['data'])); file_get_contents zajmuje się dekodowaniem i danymi: // header
Nande
5
<html>
    <head>
        <title>Ajax file upload</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
        <script>
            $(document).ready(function (e) {
            $("#uploadimage").on('submit', (function(e) {
            e.preventDefault();
                    $.ajax({
                    url: "upload.php", // Url to which the request is send
                            type: "POST", // Type of request to be send, called as method
                            data: new FormData(this), // Data sent to server, a set of key/value pairs (i.e. form fields and values)
                            contentType: false, // The content type used when sending data to the server.
                            cache: false, // To unable request pages to be cached
                            processData:false, // To send DOMDocument or non processed data file it is set to false
                            success: function(data)   // A function to be called if request succeeds
                            {
                            alert(data);
                            }
                    });
            }));
        </script>
    </head>
    <body>
        <div class="main">
            <h1>Ajax Image Upload</h1><br/>
            <hr>
            <form id="uploadimage" action="" method="post" enctype="multipart/form-data">
                <div id="image_preview"><img id="previewing" src="noimage.png" /></div>
                <hr id="line">
                <div id="selectImage">
                    <label>Select Your Image</label><br/>
                    <input type="file" name="file" id="file" required />
                    <input type="submit" value="Upload" class="submit" />
                </div>
            </form>
        </div>
    </body>
</html>
Nikit Barochija
źródło
4

Możesz użyć metody ajaxSubmit w następujący sposób :) po wybraniu pliku, który wymaga przesłania na serwer, prześlij go na serwer :)

$(document).ready(function () {
    var options = {
    target: '#output',   // target element(s) to be updated with server response
    timeout: 30000,
    error: function (jqXHR, textStatus) {
            $('#output').html('have any error');
            return false;
        }
    },
    success: afterSuccess,  // post-submit callback
    resetForm: true
            // reset the form after successful submit
};

$('#idOfInputFile').on('change', function () {
    $('#idOfForm').ajaxSubmit(options);
    // always return false to prevent standard browser submit and page navigation
    return false;
});
});
Quy Le
źródło
2
Wierzę, że mówisz o wtyczce formularza jquery . To naprawdę najlepsza opcja tutaj, oprócz braku szczegółów w odpowiedzi.
fotanus
@fotanus masz rację! ten skrypt musi korzystać z wtyczki formularza jquery, aby przesłać metodę ajaxSubmit, która definiuje wtyczkę formy jquery
Quy Le
4

aby przesłać plik przesłany przez użytkownika jako część formularza za pomocą jquery, postępuj zgodnie z poniższym kodem:

var formData = new FormData();
formData.append("userfile", fileInputElement.files[0]);

Następnie wyślij obiekt danych formularza na serwer.

Możemy również dołączyć plik lub obiekt Blob bezpośrednio do obiektu FormData.

data.append("myfile", myBlob, "filename.txt");
VISHNU Radhakrishnan
źródło
3

Jeśli chcesz przesłać plik za pomocą AJAX, oto kod, którego możesz użyć do przesłania pliku.

$(document).ready(function() {
    var options = { 
                beforeSubmit:  showRequest,
        success:       showResponse,
        dataType: 'json' 
        }; 
    $('body').delegate('#image','change', function(){
        $('#upload').ajaxForm(options).submit();        
    }); 
});     
function showRequest(formData, jqForm, options) { 
    $("#validation-errors").hide().empty();
    $("#output").css('display','none');
    return true; 
} 
function showResponse(response, statusText, xhr, $form)  { 
    if(response.success == false)
    {
        var arr = response.errors;
        $.each(arr, function(index, value)
        {
            if (value.length != 0)
            {
                $("#validation-errors").append('<div class="alert alert-error"><strong>'+ value +'</strong><div>');
            }
        });
        $("#validation-errors").show();
    } else {
         $("#output").html("<img src='"+response.file+"' />");
         $("#output").css('display','block');
    }
}

Oto kod HTML do przesłania pliku

<form class="form-horizontal" id="upload" enctype="multipart/form-data" method="post" action="upload/image'" autocomplete="off">
    <input type="file" name="image" id="image" /> 
</form>
Nikunj K.
źródło
3

Aby uzyskać wszystkie dane wejściowe formularza, w tym typ = "plik" , musisz użyć obiektu FormData . po przesłaniu formularza zobaczysz zawartość formData w debuggerze -> sieć -> Nagłówki .

var url = "YOUR_URL";

var form = $('#YOUR_FORM_ID')[0];
var formData = new FormData(form);


$.ajax(url, {
    method: 'post',
    processData: false,
    contentType: false,
    data: formData
}).done(function(data){
    if (data.success){ 
        alert("Files uploaded");
    } else {
        alert("Error while uploading the files");
    }
}).fail(function(data){
    console.log(data);
    alert("Error while uploading the files");
});
David
źródło
2
var dataform = new FormData($("#myform")[0]);
//console.log(dataform);
$.ajax({
    url: 'url',
    type: 'POST',
    data: dataform,
    async: false,
    success: function(res) {
        response data;
    },
    cache: false,
    contentType: false,
    processData: false
});
Jayesh Paunikar
źródło
5
możesz poprawić swoją odpowiedź, dodając kilka szczegółów
SR
1

Oto pomysł, o którym myślałem:

Have an iframe on page and have a referencer.

Mają formę, w której przenosisz element INPUT: File.

Form:  A processing page AND a target of the FRAME.

Wynik zostanie opublikowany w ramce, a następnie możesz po prostu wysłać pobrane dane na wyższy poziom do wybranego znacznika obrazu za pomocą czegoś takiego:

data:image/png;base64,asdfasdfasdfasdfa

i strona się ładuje.

Wierzę, że to działa dla mnie i zależnie od tego możesz zrobić coś takiego:

.aftersubmit(function(){
    stopPropigation()// or some other code which would prevent a refresh.
});
Fallenreaper
źródło
Nie rozumiem, jak to poprawia jakąkolwiek inną odpowiedź udzieloną wcześniej. Także to propagacja, a nie propagacja! ;)
JDuarteDJ