Wie kann ich Dateien asynchron hochladen?


2914

Ich möchte eine Datei asynchron mit jQuery hochladen.

$(document).ready(function () {
    $("#uploadbutton").click(function () {
        var filename = $("#file").val();

        $.ajax({
            type: "POST",
            url: "addFile.do",
            enctype: 'multipart/form-data',
            data: {
                file: filename
            },
            success: function () {
                alert("Data Uploaded: ");
            }
        });
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>

Anstatt die Datei hochzuladen, erhalte ich nur den Dateinamen. Was kann ich tun, um dieses Problem zu beheben?


Es gibt verschiedene vorgefertigte Plugins zum Hochladen von Dateien für jQuery. Diese Art des Hochladens von Hacks ist keine erfreuliche Erfahrung, daher nutzen die Leute gerne vorgefertigte Lösungen. Hier einige Beispiele: - JQuery File Uploader - Plugin zum Hochladen mehrerer Dateien - Mini-Upload mehrerer Dateien - Hochladen von jQuery-Dateien Sie können auf NPM (mit dem Schlüsselwort "jquery-plugin") oder auf Github nach weiteren Projekten suchen.
Fröhlich

72
Sie erhalten nur den Dateinamen, weil Ihr var-Dateiname den Wert $ ('# file') erhält, nicht die Datei, die in der Eingabe liegt
Jimmy

21
Hier ist eine gute: http://blueimp.github.io/jQuery-File-Upload/ - HTML5-Ajax-Upload - Anmutiger Rückgriff auf Iframes für nicht unterstützte Browser - Asynchroner Upload mehrerer Dateien Wir haben ihn verwendet und er funktioniert hervorragend. ( Dokumentation hier )
Ashish Panery

3
Überprüfen Sie auch dies: stackoverflow.com/questions/6974684/… , hier wird erklärt, wie dies über jQuery erreicht wird
Chococroc

2
@ Jimmy Wie würde er die Datei bekommen, die stattdessen in der Eingabe liegt?
Alex

Antworten:


2519

Mit HTML5 können Sie mit Ajax und jQuery Datei-Uploads durchführen. Darüber hinaus können Sie Dateiüberprüfungen (Name, Größe und MIME-Typ) durchführen oder das Fortschrittsereignis mit dem HTML5-Fortschritts-Tag (oder einem div) behandeln. Vor kurzem musste ich einen Datei-Uploader erstellen, wollte aber kein Flash verwenden noch Iframes oder Plugins verwenden, und nach einigen Recherchen kam ich auf die Lösung.

Der HTML:

<form enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>
<progress></progress>

Zunächst können Sie eine Validierung durchführen, wenn Sie möchten. Zum Beispiel im .on('change')Fall der Datei:

$(':file').on('change', function () {
  var file = this.files[0];

  if (file.size > 1024) {
    alert('max upload size is 1k');
  }

  // Also see .name, .type
});

Nun das $.ajax()Senden mit dem Klick der Schaltfläche:

$(':button').on('click', function () {
  $.ajax({
    // Your server script to process the upload
    url: 'upload.php',
    type: 'POST',

    // Form data
    data: new FormData($('form')[0]),

    // Tell jQuery not to process data or worry about content-type
    // You *must* include these options!
    cache: false,
    contentType: false,
    processData: false,

    // Custom XMLHttpRequest
    xhr: function () {
      var myXhr = $.ajaxSettings.xhr();
      if (myXhr.upload) {
        // For handling the progress of the upload
        myXhr.upload.addEventListener('progress', function (e) {
          if (e.lengthComputable) {
            $('progress').attr({
              value: e.loaded,
              max: e.total,
            });
          }
        }, false);
      }
      return myXhr;
    }
  });
});

Wie Sie sehen können, wird das Hochladen von HTML5-Dateien (und einigen Recherchen) nicht nur möglich, sondern auch sehr einfach. Probieren Sie es mit Google Chrome aus, da einige der HTML5-Komponenten der Beispiele nicht in jedem Browser verfügbar sind.


14
Kann ich dann $ _FILES in der upload.php verwenden?
Alessandro Cosentino

71
Dies sollte in Internet Explorer funktionieren, aber nur in Version 10. ( caniuse.com/xhr2 )
Tyler

18
Hallo, ich schätze, dass PHP Ihre bevorzugte Sprache ist ... aber ich frage mich, ob Sie wissen, ob dies auch in ASP.NET MVC funktioniert? Ich bin ein .NET-Entwickler und habe versucht, Ihr einfaches Beispiel zum Hochladen von AJAX-Dateien zu verwenden, aber auf der Serverseite erhalte ich die Datei, die ich über AJAX gepostet habe, nicht. Ich verwende das neueste Chrome.
Shumii

25
Es ist FormData, die hier die ganze Magie macht. Überprüfen Sie unbedingt diese Dokumente - sie decken alle Ihre Fragen zu mehreren Dateien und Feldern ab.
Inkarnation

4
Nur damit jemand anderes keine Stunden verbringt ... das name="file"ist sehr wichtig für das <input>Datei-Tag, wenn Sie die Daten in PHP (und wahrscheinlich an anderen Orten) verwenden möchten. Ich habe ein Formular dynamisch mit Javascript erstellt, sodass ich das Namensattribut nicht benötigte, aber herausgefunden habe, auf welche harte Weise Sie es unbedingt benötigen, um die Datenserverseite abzurufen.
Kivak Wolf

273

Update 2019: Dies hängt immer noch von den Browsern ab, die Ihre demografische Gruppe verwendet.

Eine wichtige Sache, die Sie mit der "neuen" HTML5- fileAPI verstehen sollten, ist, dass sie erst in IE 10 unterstützt wurde . Wenn der von Ihnen angestrebte spezifische Markt eine überdurchschnittliche Neigung zu älteren Windows-Versionen aufweist, haben Sie möglicherweise keinen Zugriff darauf.

Ab 2017 sind etwa 5% der Browser IE 6, 7, 8 oder 9. Wenn Sie in ein großes Unternehmen eintreten (z. B. ein B2B-Tool oder etwas, das Sie für Schulungen bereitstellen), kann diese Zahl in die Höhe schnellen . 2016 habe ich mich mit einem Unternehmen befasst, das IE8 auf über 60% seiner Maschinen verwendet.

Es ist 2019 ab dieser Bearbeitung, fast 11 Jahre nach meiner ersten Antwort. IE9 und niedriger sind global um die 1% -Marke, aber es gibt immer noch Cluster mit höherer Nutzung.

Das Wichtigste dabei ist, unabhängig von der Funktion, zu überprüfen, welchen Browser Ihre Benutzer verwenden . Wenn Sie dies nicht tun, lernen Sie schnell und schmerzhaft, warum "funktioniert für mich" nicht gut genug ist, um einem Kunden etwas zu liefern. caniuse ist ein nützliches Werkzeug, aber beachten Sie, woher sie ihre Demografie beziehen . Sie stimmen möglicherweise nicht mit Ihren überein. Dies ist niemals wahrer als in Unternehmensumgebungen.

Meine Antwort von 2008 folgt.


Es gibt jedoch praktikable Nicht-JS-Methoden zum Hochladen von Dateien. Sie können einen Iframe auf der Seite erstellen (die Sie mit CSS ausblenden) und dann Ihr Formular so ausrichten, dass es auf diesem Iframe veröffentlicht wird. Die Hauptseite muss nicht verschoben werden.

Es ist ein "echter" Beitrag, daher ist er nicht vollständig interaktiv. Wenn Sie Status benötigen, benötigen Sie etwas Server-seitiges, um dies zu verarbeiten. Dies ist je nach Server sehr unterschiedlich. ASP.NET hat schönere Mechanismen. PHP Plain schlägt fehl, aber Sie können Perl- oder Apache-Modifikationen verwenden, um es zu umgehen.

Wenn Sie mehrere Datei-Uploads benötigen, ist es am besten, jede Datei einzeln auszuführen (um die maximalen Limits für das Hochladen von Dateien zu überwinden). Veröffentlichen Sie das erste Formular im Iframe, überwachen Sie den Fortschritt anhand der oben genannten Informationen. Wenn es fertig ist, senden Sie das zweite Formular in den Iframe und so weiter.

Oder verwenden Sie eine Java / Flash-Lösung. Sie sind viel flexibler in dem, was sie mit ihren Posts machen können ...


142
Für die Aufzeichnung ist es jetzt möglich, reine AJAX-Datei-Uploads
durchzuführen,

Iframe-Lösung ist ziemlich einfach und leicht zu arbeiten
Matthew Lock

Dies ist eine ziemlich alte Antwort, aber sie war etwas irreführend. IE unterstützte XHR nativ bereits in IE7 und unterstützte es über ActiveX bereits in IE5. w3schools.com/ajax/ajax_xmlhttprequest_create.asp . Die praktische Möglichkeit bestand darin, auf Flash-Komponenten (Stoßwellenkomponenten) abzuzielen oder ein Flash / ActiveX-Steuerelement (Silverlight) einzuführen. Wenn Sie eine Anfrage erstellen und die Antwort über Javascript verarbeiten können, ist dies Ajax. Allerdings ist Ajax gleichbedeutend mit xhr, beschreibt jedoch nicht selbst den Unterstreichungsmechanismus / die Komponenten, die die Nutzdaten liefern / austauschen.
Brett Caswell

4
@BrettCaswell Ich habe nicht gesagt, dass AJAX / XHR nicht möglich sind, nur dass es nicht möglich ist, eine Datei mit ihnen auf alten, aber immer lebenden Versionen von IE zu veröffentlichen. Das war und ist völlig richtig.
Oli

Das ist nicht so, das ist eine UX-Meinung - vielleicht gültig.
Nimjox

112

Ich empfehle zu diesem Zweck das Fine Uploader Plugin. Ihr JavaScriptCode wäre:

$(document).ready(function() {
  $("#uploadbutton").jsupload({
    action: "addFile.do",
    onComplete: function(response){
      alert( "server response: " + response);
    }
  });
});

Es verwendet JSON - daher ist es für die alte PHP-Version nicht möglich.
Lorenzo Manucci

Scheint viel sauberer zu sein als Ajax File Upload, wo ich einen riesigen Code einfügen muss, um das verdammte Ding zu benutzen.
Ripper234

Neuere URL für Version 2 ist jetzt valums-file-uploader.github.com/file-uploader
Simon East

35
"Dieses Plugin ist Open Source unter GNU GPL 2 oder höher und GNU LGPL 2 oder höher." Solange Sie die Kopie oder eine geänderte Version nicht verteilen, müssen Sie Ihr Projekt nicht öffnen.
Trantor Liu

Vermisse ich etwas Diese Bibliothek scheint keine jquery mehr zu verwenden, unterstützt also nicht die Syntax aus der Antwort?
James McCormack

102

Hinweis: Diese Antwort ist veraltet. Es ist jetzt möglich, Dateien mit XHR hochzuladen.


Sie können keine Dateien mit XMLHttpRequest (Ajax) hochladen . Sie können den Effekt mit einem Iframe oder Flash simulieren. Das ausgezeichnete jQuery Form Plugin , das Ihre Dateien über einen Iframe veröffentlicht, um den Effekt zu erzielen.


1
Ja, Sie können auf einen Iframe POSTEN und die Datei dort erfassen. Ich habe jedoch nur sehr begrenzte Erfahrungen damit, daher kann ich dies nicht wirklich kommentieren.
Mattias

15
Kleine Bemerkung: In den neuesten Versionen von Chrome und Firefox ist es möglich, stackoverflow.com/questions/4856917/…
Alleo

Nicht unterstützt in IE9 und weniger
Radmation

96

Zusammenfassung für zukünftige Leser.

Asynchrones Hochladen von Dateien

Mit HTML5

Sie können Dateien mit jQuery mithilfe der $.ajax()Methode hochladen , wenn FormData und die Datei-API unterstützt werden (beide HTML5-Funktionen).

Sie können Dateien auch ohne FormData senden. In beiden Fällen muss jedoch die Datei-API vorhanden sein, damit Dateien so verarbeitet werden können, dass sie mit XMLHttpRequest (Ajax) gesendet werden können .

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  data: new FormData($('#formWithFiles')[0]), // The form with the file inputs.
  processData: false,
  contentType: false                    // Using FormData, no need to process data.
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

Ein schnelles, reines JavaScript-Beispiel ( kein jQuery ) finden Sie unter " Senden von Dateien mit einem FormData-Objekt ".

Zurückfallen

Wenn HTML5 nicht unterstützt wird (keine Datei-API ), ist die einzige andere reine JavaScript-Lösung (kein Flash oder ein anderes Browser-Plugin) die versteckte Iframe- Technik, mit der eine asynchrone Anforderung ohne Verwendung des XMLHttpRequest- Objekts emuliert werden kann.

Es besteht darin, einen Iframe als Ziel des Formulars mit den Dateieingaben festzulegen. Wenn der Benutzer eine Anfrage sendet, werden die Dateien hochgeladen, aber die Antwort wird im Iframe angezeigt, anstatt die Hauptseite erneut zu rendern. Durch das Ausblenden des Iframes wird der gesamte Prozess für den Benutzer transparent und eine asynchrone Anforderung emuliert.

Wenn es richtig gemacht wird, sollte es praktisch in jedem Browser funktionieren, aber es gibt einige Einschränkungen, wie man die Antwort vom Iframe erhält.

In diesem Fall können Sie es vorziehen ein Wrapper - Plugin wie verwenden Bifröst die die verwendet iframe - Technik , sondern bietet auch einen Transport jQuery Ajax ermöglicht zu Dateien senden nur mit dem $.ajax()Verfahren wie folgt aus :

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  // Set the transport to use (iframe means to use Bifröst)
  // and the expected data type (json in this case).
  dataType: 'iframe json',                                
  fileInputs: $('input[type="file"]'),  // The file inputs containing the files to send.
  data: { msg: 'Some extra data you might need.'}
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

Plugins

Bifröst ist nur ein kleiner Wrapper, der die Ajax-Methode von jQuery um Fallback-Unterstützung erweitert. Viele der oben genannten Plugins wie das jQuery Form Plugin oder das Hochladen von jQuery-Dateien enthalten jedoch den gesamten Stapel von HTML5 zu verschiedenen Fallbacks und einige nützliche Funktionen, um den Prozess zu vereinfachen. Abhängig von Ihren Anforderungen und Anforderungen möchten Sie möglicherweise eine reine Implementierung oder eines dieser Plugins in Betracht ziehen.


3
Eines ist zu beachten, basierend auf der Dokumentation: Sie sollten auch senden contentType: false. Wenn ich dies nicht mit Chrome gesendet habe, wurde der Formularinhaltstyp von jQuery ungültig gemacht.
Asche

Gute Antwort. Einige Verbesserungsvorschläge: Entfernen Sie die Teile des Codes, die nicht mit der Antwort zusammenhängen, z. B. .done()und .fail()Rückrufe. Auch ein Beispiel ohne die Verwendung von FormDataund eine Liste von Vor- und Nachteilen wäre fantastisch.
Zero3

Ich habe diesen Fehler erhalten:TypeError: Argument 1 of FormData.constructor does not implement interface HTMLFormElement.
Candlejack

85

Dieses jQuery-Plugin zum Hochladen von AJAX-Dateien lädt die Datei irgendwo hoch und leitet die Antwort an einen Rückruf weiter, sonst nichts.

  • Es hängt nicht von spezifischem HTML ab, geben Sie ihm einfach ein <input type="file">
  • Ihr Server muss nicht auf eine bestimmte Weise antworten
  • Es spielt keine Rolle, wie viele Dateien Sie verwenden oder wo sie sich auf der Seite befinden

- Verwenden Sie so wenig wie -

$('#one-specific-file').ajaxfileupload({
  'action': '/upload.php'
});

- oder so viel wie -

$('input[type="file"]').ajaxfileupload({
  'action': '/upload.php',
  'params': {
    'extra': 'info'
  },
  'onComplete': function(response) {
    console.log('custom handler for file:');
    alert(JSON.stringify(response));
  },
  'onStart': function() {
    if(weWantedTo) return false; // cancels upload
  },
  'onCancel': function() {
    console.log('no file selected');
  }
});

1
@ user840250 jQuery 1.9.1?
Jordan Feldstein

62

Ich habe das folgende Skript verwendet, um Bilder hochzuladen, was zufällig gut funktioniert.

HTML

<input id="file" type="file" name="file"/>
<div id="response"></div>

JavaScript

jQuery('document').ready(function(){
    var input = document.getElementById("file");
    var formdata = false;
    if (window.FormData) {
        formdata = new FormData();
    }
    input.addEventListener("change", function (evt) {
        var i = 0, len = this.files.length, img, reader, file;

        for ( ; i < len; i++ ) {
            file = this.files[i];

            if (!!file.type.match(/image.*/)) {
                if ( window.FileReader ) {
                    reader = new FileReader();
                    reader.onloadend = function (e) {
                        //showUploadedItem(e.target.result, file.fileName);
                    };
                    reader.readAsDataURL(file);
                }

                if (formdata) {
                    formdata.append("image", file);
                    formdata.append("extra",'extra-data');
                }

                if (formdata) {
                    jQuery('div#response').html('<br /><img src="ajax-loader.gif"/>');

                    jQuery.ajax({
                        url: "upload.php",
                        type: "POST",
                        data: formdata,
                        processData: false,
                        contentType: false,
                        success: function (res) {
                         jQuery('div#response').html("Successfully uploaded");
                        }
                    });
                }
            }
            else
            {
                alert('Not a vaild image!');
            }
        }

    }, false);
});

Erläuterung

Ich verwende die Antwort div, um die Upload-Animation und die Antwort nach dem Hochladen anzuzeigen.

Das Beste daran ist, dass Sie zusätzliche Daten wie IDs usw. mit der Datei senden können, wenn Sie dieses Skript verwenden. Ich habe es extra-datawie im Drehbuch erwähnt.

Auf PHP-Ebene funktioniert dies wie beim normalen Hochladen von Dateien. Zusätzliche Daten können als $_POSTDaten abgerufen werden.

Hier benutzt du kein Plugin und so. Sie können den Code beliebig ändern. Sie codieren hier nicht blind. Dies ist die Kernfunktionalität jedes Hochladens von jQuery-Dateien. Eigentlich Javascript.


5
-1 für die Verwendung von jQuery und nicht für die Verwendung der Selector-Engine und der Ereignishandler. addEventListenerist nicht browserübergreifend.
Mark

3
Weil es sinnlos wäre, mit nur wenigen Änderungen eine separate Antwort hinzuzufügen, die größtenteils auf dieser basiert. Stattdessen sollte diese Antwort korrigiert werden.
Mark

2
@RainFromHeaven, bitte, können Sie die Antwort bearbeiten? Ich weiß nicht, wie ich es browserübergreifend machen soll.
Thiago Negri

2
Funktioniert immer noch nicht in IE 9 und niedriger. Viele Benutzer verwenden diese IE-Versionen weiterhin.
Pierre

1
Kann jemand bitte erklären, wie dies in asp.net funktionieren kann? Benutze ich die Webmethode? Wenn ja, wie würde es aussehen?
SamuraiJack

49

Sie können es ziemlich einfach in Vanille-JavaScript tun. Hier ist ein Ausschnitt aus meinem aktuellen Projekt:

var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(e) {
    var percent = (e.position/ e.totalSize);
    // Render a pretty progress bar
};
xhr.onreadystatechange = function(e) {
    if(this.readyState === 4) {
        // Handle file upload complete
    }
};
xhr.open('POST', '/upload', true);
xhr.setRequestHeader('X-FileName',file.name); // Pass the filename along
xhr.send(file);

3
@ Gary: Sorry, ich hätte das auch posten sollen. Ich habe gerade die neue Drag & Drop-Funktion in HTML5 verwendet. Ein Beispiel finden Sie hier: html5demos.com/file-api#view-source - klicken Sie einfach auf "Quelltext anzeigen". Im Wesentlichen können Sie innerhalb der ondropVeranstaltung tunvar file = e.dataTransfer.files[0]
mpen

Vielleicht wurde die Frage seitdem bearbeitet, aber einige Leute in einer von mir eröffneten Diskussion denken, dass eine Vanilla JS-Antwort nicht zum Thema gehört, wenn OP nach einer jQuery-Lösung fragt (sofern eine existiert) und solche Antworten zu einer separaten Frage gehören.
Andy

4
@ Andy Nun, ich bin anderer Meinung, und es scheint, dass 34 andere es auch tun. Wenn Sie jQuery verwenden können, können Sie sicherlich JavaScript verwenden. Auf jeden Fall ist dies eine Community-Site - ich versuche hier nicht nur OP zu helfen. Jeder kann die Antwort wählen / verwenden, die ihm am besten gefällt. Einige Leute tendieren einfach zu jQuery, weil sie denken, dass es so viel einfacher / weniger Codezeilen sein wird, wenn sie wirklich überhaupt nicht den Overhead einer zusätzlichen Bibliothek benötigen.
Mpen

47

Sie können einfach mit jQuery hochladen .ajax().

HTML:

<form id="upload-form">
    <div>
        <label for="file">File:</label>
        <input type="file" id="file" name="file" />
        <progress class="progress" value="0" max="100"></progress>
    </div>
    <hr />
    <input type="submit" value="Submit" />
</form>

CSS

.progress { display: none; }

Javascript:

$(document).ready(function(ev) {
    $("#upload-form").on('submit', (function(ev) {
        ev.preventDefault();
        $.ajax({
            xhr: function() {
                var progress = $('.progress'),
                    xhr = $.ajaxSettings.xhr();

                progress.show();

                xhr.upload.onprogress = function(ev) {
                    if (ev.lengthComputable) {
                        var percentComplete = parseInt((ev.loaded / ev.total) * 100);
                        progress.val(percentComplete);
                        if (percentComplete === 100) {
                            progress.hide().val(0);
                        }
                    }
                };

                return xhr;
            },
            url: 'upload.php',
            type: 'POST',
            data: new FormData(this),
            contentType: false,
            cache: false,
            processData: false,
            success: function(data, status, xhr) {
                // ...
            },
            error: function(xhr, status, error) {
                // ...
            }
       });
    }));
});

1
@ RaydenBlack nur jQuery.
Zayn Ali

Wie erhalte ich den Upload-Fortschritt?
Ali Sherafat

44

Der einfachste und robusteste Weg, den ich in der Vergangenheit gemacht habe, besteht darin, einfach ein verstecktes iFrame-Tag mit Ihrem Formular anzuvisieren. Anschließend wird es innerhalb des Iframes gesendet, ohne die Seite neu zu laden.

Das ist, wenn Sie kein Plugin, JavaScript oder andere Formen von "Magie" außer HTML verwenden möchten. Natürlich können Sie dies mit JavaScript kombinieren oder was haben Sie ...

<form target="iframe" action="" method="post" enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

<iframe name="iframe" id="iframe" style="display:none" ></iframe>

Sie können auch den Inhalt des Iframes onLoadauf Serverfehler oder Erfolgsantworten lesen und diesen dann an den Benutzer ausgeben.

Chrome, iFrames und onLoad

-note- Sie müssen nur weiterlesen, wenn Sie daran interessiert sind, wie Sie beim Hochladen / Herunterladen einen UI-Blocker einrichten

Derzeit löst Chrome das onLoad-Ereignis für den Iframe nicht aus, wenn es zum Übertragen von Dateien verwendet wird. Firefox, IE und Edge lösen alle das Onload-Ereignis für Dateiübertragungen aus.

Die einzige Lösung, die ich für Chrome gefunden habe, war die Verwendung eines Cookies.

Um dies im Grunde zu tun, wenn der Upload / Download gestartet wird:

  • [Client-Seite] Starten Sie ein Intervall, um nach dem Vorhandensein eines Cookies zu suchen
  • [Serverseite] Machen Sie mit den Dateidaten alles, was Sie brauchen
  • [Serverseitig] Setzen Sie das Cookie für das clientseitige Intervall
  • [Client Side] Interval sieht das Cookie und verwendet es wie das onLoad-Ereignis. Sie können beispielsweise einen UI-Blocker starten und dann beim Laden (oder wenn ein Cookie erstellt wird) den UI-Blocker entfernen.

Die Verwendung eines Cookies ist hässlich, funktioniert aber.

Ich habe ein jQuery-Plugin erstellt, um dieses Problem für Chrome beim Herunterladen zu beheben. Sie finden es hier

https://github.com/ArtisticPhoenix/jQuery-Plugins/blob/master/iDownloader.js

Das gleiche Grundprinzip gilt auch für das Hochladen.

So verwenden Sie den Downloader (natürlich auch den JS)

 $('body').iDownloader({
     "onComplete" : function(){
          $('#uiBlocker').css('display', 'none'); //hide ui blocker on complete
     }
 });

 $('somebuttion').click( function(){
      $('#uiBlocker').css('display', 'block'); //block the UI
      $('body').iDownloader('download', 'htttp://example.com/location/of/download');
 });

Erstellen Sie auf der Serverseite kurz vor dem Übertragen der Dateidaten das Cookie

 setcookie('iDownloader', true, time() + 30, "/");

Das Plugin sieht das Cookie und löst dann den onCompleteRückruf aus.


3
Ich liebe es. Wenn nur jemand die möglichen Probleme mit dieser brillanten Lösung erwähnen könnte. Ich verstehe wirklich nicht, warum Leute diese klobigen Bibliotheken und Plugins schreiben und verwenden, wenn es die Lösung gibt.
Jewgenij Afanasjew

1
Nun, ich denke, der Grund wäre, beim Hochladen einige Fortschrittsinformationen anzuzeigen.
Prakhar Mishra

32

Eine Lösung, die ich gefunden habe, war, dem <form>Ziel einen versteckten iFrame zu geben. Der iFrame kann dann JS ausführen, um dem Benutzer anzuzeigen, dass er vollständig ist (beim Laden der Seite).


1
Ich bin an dieser Antwort interessiert. Haben Sie eine Demo, auf die Sie verlinken können?
lfender6445

32

Ich habe dies in einer Rails-Umgebung geschrieben . Es sind nur etwa fünf Zeilen JavaScript, wenn Sie das leichtgewichtige jQuery-Formular-Plugin verwenden.

Die Herausforderung besteht darin, den AJAX-Upload zum Laufen zu bringen, da der Standard remote_form_fordas Übermitteln mehrteiliger Formulare nicht versteht. Die Dateidaten, die Rails mit der AJAX-Anforderung sucht, werden nicht gesendet.

Hier kommt das jQuery-Form-Plugin ins Spiel.

Hier ist der Rails-Code dafür:

<% remote_form_for(:image_form, 
                   :url => { :controller => "blogs", :action => :create_asset }, 
                   :html => { :method => :post, 
                              :id => 'uploadForm', :multipart => true }) 
                                                                        do |f| %>
 Upload a file: <%= f.file_field :uploaded_data %>
<% end %>

Hier ist das zugehörige JavaScript:

$('#uploadForm input').change(function(){
 $(this).parent().ajaxSubmit({
  beforeSubmit: function(a,f,o) {
   o.dataType = 'json';
  },
  complete: function(XMLHttpRequest, textStatus) {
   // XMLHttpRequest.responseText will contain the URL of the uploaded image.
   // Put it in an image element you create, or do with it what you will.
   // For example, if you have an image elemtn with id "my_image", then
   //  $('#my_image').attr('src', XMLHttpRequest.responseText);
   // Will set that image tag to display the uploaded image.
  },
 });
});

Und hier ist die Rails-Controller-Aktion, hübsche Vanille:

 @image = Image.new(params[:image_form])
 @image.save
 render :text => @image.public_filename

Ich habe dies in den letzten Wochen mit Bloggity verwendet und es hat wie ein Champion funktioniert.


31

Simple Ajax Uploader ist eine weitere Option:

https://github.com/LPology/Simple-Ajax-Uploader

  • Browserübergreifend - funktioniert in IE7 +, Firefox, Chrome, Safari, Opera
  • Unterstützt mehrere gleichzeitige Uploads - auch in Nicht-HTML5-Browsern
  • Kein Flash oder externes CSS - nur eine 5-KB-Javascript-Datei
  • Optionale, integrierte Unterstützung für vollständig browserübergreifende Fortschrittsbalken (unter Verwendung der APC-Erweiterung von PHP)
  • Flexibel und hochgradig anpassbar - verwenden Sie ein beliebiges Element als Upload-Schaltfläche und gestalten Sie Ihre eigenen Fortschrittsanzeigen
  • Es sind keine Formulare erforderlich. Geben Sie lediglich ein Element an, das als Upload-Schaltfläche dient
  • MIT-Lizenz - kostenlos für kommerzielle Projekte

Anwendungsbeispiel:

var uploader = new ss.SimpleUpload({
    button: $('#uploadBtn'), // upload button
    url: '/uploadhandler', // URL of server-side upload handler
    name: 'userfile', // parameter name of the uploaded file
    onSubmit: function() {
        this.setProgressBar( $('#progressBar') ); // designate elem as our progress bar
    },
    onComplete: function(file, response) {
        // do whatever after upload is finished
    }
});

2
Dies scheint das bisher vielversprechendste zu sein. Du hattest mich dabei IE7+! Probieren Sie es jetzt aus. Vielen Dank
Pierre

25

jQuery Uploadify ist ein weiteres gutes Plugin, mit dem ich zuvor Dateien hochgeladen habe. Der JavaScript-Code ist so einfach wie der folgende: Code. Die neue Version funktioniert jedoch nicht in Internet Explorer.

$('#file_upload').uploadify({
    'swf': '/public/js/uploadify.swf',
    'uploader': '/Upload.ashx?formGuid=' + $('#formGuid').val(),
    'cancelImg': '/public/images/uploadify-cancel.png',
    'multi': true,
    'onQueueComplete': function (queueData) {
        // ...
    },
    'onUploadStart': function (file) {
        // ...
    }
});

Ich habe viel gesucht und bin zu einer anderen Lösung für das Hochladen von Dateien ohne Plugin und nur mit Ajax gekommen. Die Lösung ist wie folgt:

$(document).ready(function () {
    $('#btn_Upload').live('click', AjaxFileUpload);
});

function AjaxFileUpload() {
    var fileInput = document.getElementById("#Uploader");
    var file = fileInput.files[0];
    var fd = new FormData();
    fd.append("files", file);
    var xhr = new XMLHttpRequest();
    xhr.open("POST", 'Uploader.ashx');
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
             alert('success');
        }
        else if (uploadResult == 'success')
            alert('error');
    };
    xhr.send(fd);
}

2
Uploadify ist seit Jahren tot. Wird nicht mehr unterstützt oder gewartet.
Ray Nicholus

24

Hier ist nur eine weitere Lösung zum Hochladen von Dateien ( ohne Plugin) ).

Verwenden einfacher Javascripts und AJAX (mit Fortschrittsbalken)

HTML-Teil

<form id="upload_form" enctype="multipart/form-data" method="post">
    <input type="file" name="file1" id="file1"><br>
    <input type="button" value="Upload File" onclick="uploadFile()">
    <progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
    <h3 id="status"></h3>
    <p id="loaded_n_total"></p>
</form>

JS Teil

function _(el){
    return document.getElementById(el);
}
function uploadFile(){
    var file = _("file1").files[0];
    // alert(file.name+" | "+file.size+" | "+file.type);
    var formdata = new FormData();
    formdata.append("file1", file);
    var ajax = new XMLHttpRequest();
    ajax.upload.addEventListener("progress", progressHandler, false);
    ajax.addEventListener("load", completeHandler, false);
    ajax.addEventListener("error", errorHandler, false);
    ajax.addEventListener("abort", abortHandler, false);
    ajax.open("POST", "file_upload_parser.php");
    ajax.send(formdata);
}
function progressHandler(event){
    _("loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "+event.total;
    var percent = (event.loaded / event.total) * 100;
    _("progressBar").value = Math.round(percent);
    _("status").innerHTML = Math.round(percent)+"% uploaded... please wait";
}
function completeHandler(event){
    _("status").innerHTML = event.target.responseText;
    _("progressBar").value = 0;
}
function errorHandler(event){
    _("status").innerHTML = "Upload Failed";
}
function abortHandler(event){
    _("status").innerHTML = "Upload Aborted";
}

PHP-Teil

<?php
$fileName = $_FILES["file1"]["name"]; // The file name
$fileTmpLoc = $_FILES["file1"]["tmp_name"]; // File in the PHP tmp folder
$fileType = $_FILES["file1"]["type"]; // The type of file it is
$fileSize = $_FILES["file1"]["size"]; // File size in bytes
$fileErrorMsg = $_FILES["file1"]["error"]; // 0 for false... and 1 for true
if (!$fileTmpLoc) { // if file not chosen
    echo "ERROR: Please browse for a file before clicking the upload button.";
    exit();
}
if(move_uploaded_file($fileTmpLoc, "test_uploads/$fileName")){ // assuming the directory name 'test_uploads'
    echo "$fileName upload is complete";
} else {
    echo "move_uploaded_file function failed";
}
?>

Hier ist die BEISPIEL-Anwendung


19
var formData=new FormData();
formData.append("fieldname","value");
formData.append("image",$('[name="filename"]')[0].files[0]);

$.ajax({
    url:"page.php",
    data:formData,
    type: 'POST',
    dataType:"JSON",
    cache: false,
    contentType: false,
    processData: false,
    success:function(data){ }
});

Sie können Formulardaten verwenden, um alle Ihre Werte einschließlich Bilder zu veröffentlichen.


6
Hinweis: cache: falseIst bei einer POSTAnforderung redundant, da POST niemals zwischengespeichert wird.
Gone Coding

@ Vivek Aasaithambi, ich habe diesen Fehler erhalten:TypeError: Argument 1 of FormData.constructor does not implement interface HTMLFormElement.
Candlejack

15

Führen Sie die folgenden Schritte aus, um eine Datei asynchron mit Jquery hochzuladen:

Schritt 1 Öffnen Sie in Ihrem Projekt den Nuget-Manager und fügen Sie ein Paket hinzu (jquery fileupload (nur Sie müssen es in das Suchfeld schreiben, es wird angezeigt)) URL: https://github.com/blueimp/jQuery-File- Hochladen

Schritt 2 Fügen Sie die folgenden Skripte in die HTML-Dateien ein, die dem Projekt bereits hinzugefügt wurden, indem Sie das obige Paket ausführen:

jquery.ui.widget.js

jquery.iframe-transport.js

jquery.fileupload.js

Schritt 3 Schreiben Sie die Steuerung zum Hochladen von Dateien gemäß dem folgenden Code:

<input id="upload" name="upload" type="file" />

Schritt 4 Schreiben Sie eine js-Methode als uploadFile wie folgt:

 function uploadFile(element) {

            $(element).fileupload({

                dataType: 'json',
                url: '../DocumentUpload/upload',
                autoUpload: true,
                add: function (e, data) {           
                  // write code for implementing, while selecting a file. 
                  // data represents the file data. 
                  //below code triggers the action in mvc controller
                  data.formData =
                                    {
                                     files: data.files[0]
                                    };
                  data.submit();
                },
                done: function (e, data) {          
                   // after file uploaded
                },
                progress: function (e, data) {

                   // progress
                },
                fail: function (e, data) {

                   //fail operation
                },
                stop: function () {

                  code for cancel operation
                }
            });

        };

Schritt 5 Laden Sie beim Hochladen der Elementdatei die fertige Funktion auf, um den Vorgang wie folgt zu starten:

$(document).ready(function()
{
    uploadFile($('#upload'));

});

Schritt 6 Schreiben Sie den MVC-Controller und die Aktion wie folgt:

public class DocumentUploadController : Controller
    {       

        [System.Web.Mvc.HttpPost]
        public JsonResult upload(ICollection<HttpPostedFileBase> files)
        {
            bool result = false;

            if (files != null || files.Count > 0)
            {
                try
                {
                    foreach (HttpPostedFileBase file in files)
                    {
                        if (file.ContentLength == 0)
                            throw new Exception("Zero length file!");                       
                        else 
                            //code for saving a file

                    }
                }
                catch (Exception)
                {
                    result = false;
                }
            }


            return new JsonResult()
                {
                    Data=result
                };


        }

    }

14

Ein moderner Ansatz ohne Jquery besteht darin, das FileList- Objekt zu verwenden, von dem Sie zurückkommen, <input type="file">wenn der Benutzer eine Datei auswählt, und dann mit Fetch die um ein FormData- Objekt gewickelte FileList zu veröffentlichen .

// The input DOM element // <input type="file">
const inputElement = document.querySelector('input[type=file]');

// Listen for a file submit from user
inputElement.addEventListener('change', () => {
    const data = new FormData();
    data.append('file', inputElement.files[0]);
    data.append('imageName', 'flower');

    // You can then post it to your server.
    // Fetch can accept an object of type FormData on its  body
    fetch('/uploadImage', {
        method: 'POST',
        body: data
    });
});

Anscheinend nicht unterstützt auf IE
Marco Demaio

11

Sie können eine Lösung gelöst mit einem Arbeits Demo sehen hier , dass Sie Formulardateien an den Server , um eine Vorschau und senden kann. In Ihrem Fall müssen Sie Ajax verwenden , um das Hochladen von Dateien auf den Server zu erleichtern:

<from action="" id="formContent" method="post" enctype="multipart/form-data">
    <span>File</span>
    <input type="file" id="file" name="file" size="10"/>
    <input id="uploadbutton" type="button" value="Upload"/>
</form>

Die übermittelten Daten sind Formulardaten. Verwenden Sie in Ihrer jQuery eine Formularübermittlungsfunktion anstelle eines Schaltflächenklicks, um die Formulardatei wie unten gezeigt zu senden.

$(document).ready(function () {
   $("#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("successfully submitted");

     });
   });
});

Weitere Details anzeigen


11

Beispiel: Wenn Sie jQuery verwenden, können Sie eine Upload-Datei einfach bearbeiten. Dies ist ein kleines und starkes jQuery-Plugin, http://jquery.malsup.com/form/ .

Beispiel

var $bar   = $('.ProgressBar');
$('.Form').ajaxForm({
  dataType: 'json',

  beforeSend: function(xhr) {
    var percentVal = '0%';
    $bar.width(percentVal);
  },

  uploadProgress: function(event, position, total, percentComplete) {
    var percentVal = percentComplete + '%';
    $bar.width(percentVal)
  },

  success: function(response) {
    // Response
  }
});

Ich hoffe es wäre hilfreich


10

Sie können verwenden

$(function() {
    $("#file_upload_1").uploadify({
        height        : 30,
        swf           : '/uploadify/uploadify.swf',
        uploader      : '/uploadify/uploadify.php',
        width         : 120
    });
});

Demo


9

Konvertieren Sie die Datei mit readAsDataURL () von | HTML5 oder einem Base64-Encoder in base64 . Geige hier

var reader = new FileReader();

        reader.onload = function(readerEvt) {
            var binaryString = readerEvt.target.result;
            document.getElementById("base64textarea").value = btoa(binaryString);
        };

        reader.readAsBinaryString(file);

Dann abrufen:

window.open("data:application/octet-stream;base64," + base64);

9

Sie können zusätzliche Parameter zusammen mit dem Dateinamen beim asynchronen Hochladen mit XMLHttpRequest übergeben (ohne Flash- und Iframe-Abhängigkeit). Fügen Sie den zusätzlichen Parameterwert mit FormData hinzu und senden Sie die Upload-Anforderung.


var formData = new FormData();
formData.append('parameter1', 'value1');
formData.append('parameter2', 'value2'); 
formData.append('file', $('input[type=file]')[0].files[0]);

$.ajax({
    url: 'post back url',
    data: formData,
// other attributes of AJAX
});

Außerdem bietet das Hochladen von JavaScript-UI-Dateien von Syncfusion eine Lösung für dieses Szenario, indem einfach ein Ereignisargument verwendet wird. Dokumentation finden Sie hier und weitere Details zu diesem Steuerelement finden Sie hier


8

Suchen Sie hier nach der asynchronen Behandlung des Upload-Vorgangs für eine Datei : https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications

Beispiel aus dem Link

<?php
if (isset($_FILES['myFile'])) {
    // Example:
    move_uploaded_file($_FILES['myFile']['tmp_name'], "uploads/" . $_FILES['myFile']['name']);
    exit;
}
?><!DOCTYPE html>
<html>
<head>
    <title>dnd binary upload</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript">
        function sendFile(file) {
            var uri = "/index.php";
            var xhr = new XMLHttpRequest();
            var fd = new FormData();

            xhr.open("POST", uri, true);
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    // Handle response.
                    alert(xhr.responseText); // handle response.
                }
            };
            fd.append('myFile', file);
            // Initiate a multipart/form-data upload
            xhr.send(fd);
        }

        window.onload = function() {
            var dropzone = document.getElementById("dropzone");
            dropzone.ondragover = dropzone.ondragenter = function(event) {
                event.stopPropagation();
                event.preventDefault();
            }

            dropzone.ondrop = function(event) {
                event.stopPropagation();
                event.preventDefault();

                var filesArray = event.dataTransfer.files;
                for (var i=0; i<filesArray.length; i++) {
                    sendFile(filesArray[i]);
                }
            }
        }
    </script>
</head>
<body>
    <div>
        <div id="dropzone" style="margin:30px; width:500px; height:300px; border:1px dotted grey;">Drag & drop your file here...</div>
    </div>
</body>
</html>

7

Das ist meine Lösung.

<form enctype="multipart/form-data">    

    <div class="form-group">
        <label class="control-label col-md-2" for="apta_Description">Description</label>
        <div class="col-md-10">
            <input class="form-control text-box single-line" id="apta_Description" name="apta_Description" type="text" value="">
        </div>
    </div>

    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

und die js

<script>

    $(':button').click(function () {
        var formData = new FormData($('form')[0]);
        $.ajax({
            url: '@Url.Action("Save", "Home")',  
            type: 'POST',                
            success: completeHandler,
            data: formData,
            cache: false,
            contentType: false,
            processData: false
        });
    });    

    function completeHandler() {
        alert(":)");
    }    
</script>

Regler

[HttpPost]
public ActionResult Save(string apta_Description, HttpPostedFileBase file)
{
    [...]
}

2
Sie scheinen eine Art Rahmen in Ihre Antwort eingemischt zu haben. Sie sollten zumindest angeben, für welchen Rahmen Ihre Antwort verwendbar ist. Besser noch, entfernen Sie alle Framework-Inhalte und geben Sie nur eine Antwort auf die gestellte Frage.
Zero3

2
Also gibt es tatsächlich ein MVC-Framework namens "MVC"? und es verwendet csharpish Syntax? das ist grausam.
Nonchip

6

Mit HTML5 und JavaScript ist das Hochladen von Async recht einfach. Ich erstelle die Upload-Logik zusammen mit Ihrem HTML-Code. Dies funktioniert nicht vollständig, da die API benötigt wird. Zeigen Sie jedoch, wie es funktioniert, wenn Sie den Endpunkt /uploadaus dem Stammverzeichnis Ihrer Website aufgerufen haben. Dieser Code sollte für Sie funktionieren:

const asyncFileUpload = () => {
  const fileInput = document.getElementById("file");
  const file = fileInput.files[0];
  const uri = "/upload";
  const xhr = new XMLHttpRequest();
  xhr.upload.onprogress = e => {
    const percentage = e.loaded / e.total;
    console.log(percentage);
  };
  xhr.onreadystatechange = e => {
    if (xhr.readyState === 4 && xhr.status === 200) {
      console.log("file uploaded");
    }
  };
  xhr.open("POST", uri, true);
  xhr.setRequestHeader("X-FileName", file.name);
  xhr.send(file);
}
<form>
  <span>File</span>
  <input type="file" id="file" name="file" size="10" />
  <input onclick="asyncFileUpload()" id="upload" type="button" value="Upload" />
</form>

Auch einige weitere Informationen zu XMLHttpReques:

Das XMLHttpRequest-Objekt

Alle modernen Browser unterstützen das XMLHttpRequest-Objekt. Das XMLHttpRequest-Objekt kann verwendet werden, um hinter den Kulissen Daten mit einem Webserver auszutauschen. Dies bedeutet, dass es möglich ist, Teile einer Webseite zu aktualisieren, ohne die gesamte Seite neu zu laden.


Erstellen Sie ein XMLHttpRequest-Objekt

Alle modernen Browser (Chrome, Firefox, IE7 +, Edge, Safari, Opera) verfügen über ein integriertes XMLHttpRequest-Objekt.

Syntax zum Erstellen eines XMLHttpRequest-Objekts:

variable = new XMLHttpRequest ();


Zugriff über Domänen hinweg

Aus Sicherheitsgründen erlauben moderne Browser keinen domänenübergreifenden Zugriff.

Dies bedeutet, dass sich sowohl die Webseite als auch die XML-Datei, die geladen werden soll, auf demselben Server befinden müssen.

In den Beispielen auf W3Schools werden alle XML-Dateien in der W3Schools-Domäne geöffnet.

Wenn Sie das obige Beispiel auf einer Ihrer eigenen Webseiten verwenden möchten, müssen sich die von Ihnen geladenen XML-Dateien auf Ihrem eigenen Server befinden.

Für weitere Details können Sie hier weiterlesen ...


5

Sie können eine neuere Fetch-API mit JavaScript verwenden. So was:

function uploadButtonCLicked(){
    var input = document.querySelector('input[type="file"]')

    fetch('/url', {
      method: 'POST',
      body: input.files[0]
    }).then(res => res.json())   // you can do something with response
      .catch(error => console.error('Error:', error))
      .then(response => console.log('Success:', response));
}                               

Vorteil: Die Fetch-API wird von allen modernen Browsern nativ unterstützt , sodass Sie nichts importieren müssen. Beachten Sie außerdem, dass fetch () ein Versprechen zurückgibt, das dann .then(..code to handle response..)asynchron verwendet wird.


4

Sie können die asynchronen Uploads mehrerer Dateien mit JavaScript oder jQuery durchführen, ohne ein Plugin zu verwenden. Sie können den Echtzeitfortschritt des Datei-Uploads auch in der Fortschrittskontrolle anzeigen. Ich bin auf 2 nette Links gestoßen -

  1. ASP.NET Web Forms-basierte Funktion zum Hochladen mehrerer Dateien mit Fortschrittsbalken
  2. ASP.NET MVC-basiertes Hochladen mehrerer Dateien in jQuery

Die serverseitige Sprache ist C #, aber Sie können einige Änderungen vornehmen, damit sie mit einer anderen Sprache wie PHP funktioniert.

Datei-Upload ASP.NET Core MVC:

In der Ansicht Steuerelement zum Hochladen von Dateien in HTML erstellen:

<form method="post" asp-action="Add" enctype="multipart/form-data">
    <input type="file" multiple name="mediaUpload" />
    <button type="submit">Submit</button>
</form>

Erstellen Sie nun eine Aktionsmethode in Ihrem Controller:

[HttpPost]
public async Task<IActionResult> Add(IFormFile[] mediaUpload)
{
    //looping through all the files
    foreach (IFormFile file in mediaUpload)
    {
        //saving the files
        string path = Path.Combine(hostingEnvironment.WebRootPath, "some-folder-path"); 
        using (var stream = new FileStream(path, FileMode.Create))
        {
            await file.CopyToAsync(stream);
        }
    }
}

Die Variable hostingEnvironment ist vom Typ IHostingEnvironment, die mithilfe der Abhängigkeitsinjektion in den Controller injiziert werden kann, z.

private IHostingEnvironment hostingEnvironment;
public MediaController(IHostingEnvironment environment)
{
    hostingEnvironment = environment;
}

Könnten Sie das Wesentliche der Lösung in Ihre Antwort aufnehmen, da sie sonst möglicherweise unbrauchbar wird, wenn sich die verlinkte Website ändert oder offline geht?
Dima Kozhevin

4

Suchen Sie für PHP nach https://developer.hyvor.com/php/image-upload-ajax-php-mysql

HTML

<html>
<head>
    <title>Image Upload with AJAX, PHP and MYSQL</title>
</head>
<body>
<form onsubmit="submitForm(event);">
    <input type="file" name="image" id="image-selecter" accept="image/*">
    <input type="submit" name="submit" value="Upload Image">
</form>
<div id="uploading-text" style="display:none;">Uploading...</div>
<img id="preview">
</body>
</html>

JAVASCRIPT

var previewImage = document.getElementById("preview"),  
    uploadingText = document.getElementById("uploading-text");

function submitForm(event) {
    // prevent default form submission
    event.preventDefault();
    uploadImage();
}

function uploadImage() {
    var imageSelecter = document.getElementById("image-selecter"),
        file = imageSelecter.files[0];
    if (!file) 
        return alert("Please select a file");
    // clear the previous image
    previewImage.removeAttribute("src");
    // show uploading text
    uploadingText.style.display = "block";
    // create form data and append the file
    var formData = new FormData();
    formData.append("image", file);
    // do the ajax part
    var ajax = new XMLHttpRequest();
    ajax.onreadystatechange = function() {
        if (this.readyState === 4 && this.status === 200) {
            var json = JSON.parse(this.responseText);
            if (!json || json.status !== true) 
                return uploadError(json.error);

            showImage(json.url);
        }
    }
    ajax.open("POST", "upload.php", true);
    ajax.send(formData); // send the form data
}

PHP

<?php
$host = 'localhost';
$user = 'user';
$password = 'password';
$database = 'database';
$mysqli = new mysqli($host, $user, $password, $database);


 try {
    if (empty($_FILES['image'])) {
        throw new Exception('Image file is missing');
    }
    $image = $_FILES['image'];
    // check INI error
    if ($image['error'] !== 0) {
        if ($image['error'] === 1) 
            throw new Exception('Max upload size exceeded');

        throw new Exception('Image uploading error: INI Error');
    }
    // check if the file exists
    if (!file_exists($image['tmp_name']))
        throw new Exception('Image file is missing in the server');
    $maxFileSize = 2 * 10e6; // in bytes
    if ($image['size'] > $maxFileSize)
        throw new Exception('Max size limit exceeded'); 
    // check if uploaded file is an image
    $imageData = getimagesize($image['tmp_name']);
    if (!$imageData) 
        throw new Exception('Invalid image');
    $mimeType = $imageData['mime'];
    // validate mime type
    $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif'];
    if (!in_array($mimeType, $allowedMimeTypes)) 
        throw new Exception('Only JPEG, PNG and GIFs are allowed');

    // nice! it's a valid image
    // get file extension (ex: jpg, png) not (.jpg)
    $fileExtention = strtolower(pathinfo($image['name'] ,PATHINFO_EXTENSION));
    // create random name for your image
    $fileName = round(microtime(true)) . mt_rand() . '.' . $fileExtention; // anyfilename.jpg
    // Create the path starting from DOCUMENT ROOT of your website
    $path = '/examples/image-upload/images/' . $fileName;
    // file path in the computer - where to save it 
    $destination = $_SERVER['DOCUMENT_ROOT'] . $path;

    if (!move_uploaded_file($image['tmp_name'], $destination))
        throw new Exception('Error in moving the uploaded file');

    // create the url
    $protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://';
    $domain = $protocol . $_SERVER['SERVER_NAME'];
    $url = $domain . $path;
    $stmt = $mysqli -> prepare('INSERT INTO image_uploads (url) VALUES (?)');
    if (
        $stmt &&
        $stmt -> bind_param('s', $url) &&
        $stmt -> execute()
    ) {
        exit(
            json_encode(
                array(
                    'status' => true,
                    'url' => $url
                )
            )
        );
    } else 
        throw new Exception('Error in saving into the database');

} catch (Exception $e) {
    exit(json_encode(
        array (
            'status' => false,
            'error' => $e -> getMessage()
        )
    ));
}

4

Sie können auch https://uppy.io verwenden .

Es lädt Dateien hoch, ohne von der Seite weg zu navigieren, und bietet einige Boni wie Drag & Drop, Fortsetzen des Uploads bei Browserabstürzen / flockigen Netzwerken und Importieren von z. B. Instagram. Es ist Open Source und basiert nicht auf jQuery / React / Angular / Vue, kann aber damit verwendet werden. Haftungsausschluss: Als Schöpfer bin ich voreingenommen;)


Link oben ist tot. Hier ist der Github: github.com/transloadit/uppy
Chris Charles

uppy.io sind CloudFlare + GitHub-Seiten gesichert und für mich bereit ? Immer noch nützlich, um den direkten Repo-Link zu haben :)
kvz
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.