2015-03-04 22 views
6

Mam duży problem z przesyłaniem wielu obrazów za pomocą AJAX. Piszę ten kod:Przesyłanie wielu obrazów przy użyciu AJAX, PHP i jQuery

HTML

<form id="upload" method="post" enctype="multipart/form-data"> 
    <div id="drop" class="drop-area"> 
     <div class="drop-area-label"> 
      Drop image here 
     </div> 
     <input type="file" name="file" id="file" multiple/> 
    </div> 

    <ul class="gallery-image-list" id="uploads"> 
    <!-- The file uploads will be shown here --> 
    </ul> 
</form> 
<div id="listTable"></div> 

jQuery/AJAX

$(document).on("change", "input[name^='file']", function(e){ 
    e.preventDefault(); 
    var This = this, 
     display = $("#uploads"); 

    // list all file data 
    $.each(This.files, function(i, obj){ 
     // for each image run script asynchronous 
     (function(i) { 
      // get data from input file 
      var file = This.files[i], 
       name = file.name, 
       size = file.size, 
       type = file.type, 
       lastModified  = file.lastModified, 
       lastModifiedDate = file.lastModifiedDate, 
       webkitRelativePath = file.webkitRelativePath, 
       slice    = file.slice, 
       i = i; 

      // DEBUG 
     /* 
      var acc = [] 
      $.each(file, function(index, value) { 
       acc.push(index + ": " + value); 
      }); 
      alert(JSON.stringify(acc)); 
     */ 

      $.ajax({ 
       url:'/ajax/upload.php', 
       contentType: "multipart/form-data", 
       data:{ 
         "image": 
         { 
          "name":name, 
          "size":size, 
          "type":type, 
          "lastModified":lastModified, 
          "lastModifiedDate":lastModifiedDate, 
          "webkitRelativePath":webkitRelativePath, 
          //"slice":slice, 
         } 
        }, 
       type: "POST", 
       // Custom XMLHttpRequest 
       xhr: function() { 
        var myXhr = $.ajaxSettings.xhr(); 
        // Check if upload property exists 
        if(myXhr.upload) 
        { 
         // For handling the progress of the upload 
         myXhr.upload.addEventListener("progress",progressHandlingFunction, false); 
        } 
        return myXhr; 
       }, 
       cache: false, 
       success : function(data){ 
        // load ajax data 
        $("#listTable").append(data); 
       } 
      }); 
      // display progress 
      function progressHandlingFunction(e){ 
       if(e.lengthComputable){ 
        var perc = Math.round((e.loaded/e.total)*100); 
        perc = ((perc >= 100) ? 100 : ((perc <= 0) ? 0 : 0)); 
       $("#progress"+i+" > div") 
        .attr({"aria-valuenow":perc}) 
         .css("width", perc+"%"); 
       } 
      } 
      // display list of files 
      display.append('<li>'+name+'</li><div class="progress" id="progress'+i+'">' 
        +'<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">' 
        +'</div></div>'); 
     })(i); 
    }); 
}); 

Próbowałem różnych wersji i nigdy nie uda się wysłać wiele danych poprzez AJAX. Próbowałem w ten sposób tego, co widzisz powyżej, a teraz otrzymuję tylko informacje POST. Rozumiem, dlaczego dostaję POST, ale muszę wysłać informacje o PLIKACH i nie wiem, gdzie się mylę.

Nie pracuję za pierwszym razem z ajaxem i często używam go w większości projektów, ale nigdy nie użyłem do wysyłania wielu plików i teraz mi to przeszkadza.

Dzięki!

+0

proszę wyjaśnić: 1. contentType jest 'wieloczęściowy/form-data' ale dane nie jest (jQuery.param przekonwertuje obiekt js do' x-www-form-urlencoded' zamiast) , więc dane zostaną utracone w tłumaczeniu. Co chcesz przekazać i jak? 2. Rzeczywiste dane obrazu nie są przesyłane, czy jest to zamierzone? 3. Jeden ajax jest wywoływany dla * każdego * pliku, powodując wiele połączeń i konfliktów w postępowaniu, czy to celowe? 4. Nie widzę żadnego kodu upuszczania. Chcesz to? – Sheepy

Odpowiedz

10

spróbować wykorzystując json przesłać, proces file obiekt

html

<div id="drop" class="drop-area ui-widget-header"> 
    <div class="drop-area-label">Drop image here</div> 
</div> 
<br /> 
<form id="upload"> 
    <input type="file" name="file" id="file" multiple="true" accepts="image/*" /> 
    <ul class="gallery-image-list" id="uploads"> 
    <!-- The file uploads will be shown here --> 
    </ul> 
</form> 
<div id="listTable"></div> 

css

#uploads { 
     display:block; 
     position:relative; 
    } 

    #uploads li { 
     list-style:none; 
    } 

    #drop { 
     width: 90%; 
     height: 100px; 
     padding: 0.5em; 
     float: left; 
     margin: 10px; 
     border: 8px dotted grey; 
    } 

    #drop.hover { 
     border: 8px dotted green; 
    } 

    #drop.err { 
     border: 8px dotted orangered; 
    } 

js

var display = $("#uploads"); // cache `#uploads`, `this` at `$.ajax()` 
var droppable = $("#drop")[0]; // cache `#drop` selector 
$.ajaxSetup({ 
    context: display, 
    contentType: "application/json", 
    dataType: "json", 
    beforeSend: function (jqxhr, settings) { 
     // pre-process `file` 
     var file = JSON.parse(
        decodeURIComponent(settings.data.split(/=/)[1]) 
        ); 
     // add `progress` element for each `file` 
     var progress = $("<progress />", { 
       "class": "file-" + (!!$("progress").length 
         ? $("progress").length 
         : "0"), 
       "min": 0, 
       "max": 0, 
       "value": 0, 
       "data-name": file.name 
     }); 
     this.append(progress, file.name + "<br />"); 
     jqxhr.name = progress.attr("class"); 
    } 
}); 

var processFiles = function processFiles(event) { 
    event.preventDefault(); 
    // process `input[type=file]`, `droppable` `file` 
    var files = event.target.files || event.dataTransfer.files; 
    var images = $.map(files, function (file, i) { 
     var reader = new FileReader(); 
     var dfd = new $.Deferred(); 
     reader.onload = function (e) { 
      dfd.resolveWith(file, [e.target.result]) 
     }; 
     reader.readAsDataURL(new Blob([file], { 
      "type": file.type 
     })); 
     return dfd.then(function (data) { 
      return $.ajax({ 
       type: "POST", 
       url: "/echo/json/", 
       data: { 
        "file": JSON.stringify({ 
          "file": data, 
          "name": this.name, 
          "size": this.size, 
          "type": this.type 
        }) 
       }, 
       xhr: function() { 
        // do `progress` event stuff 
        var uploads = this.context; 
        var progress = this.context.find("progress:last"); 
        var xhrUpload = $.ajaxSettings.xhr(); 
        if (xhrUpload.upload) { 
         xhrUpload.upload.onprogress = function (evt) { 
          progress.attr({ 
            "max": evt.total, 
            "value": evt.loaded 
          }) 
         }; 
         xhrUpload.upload.onloadend = function (evt) { 
          var progressData = progress.eq(-1); 
          console.log(progressData.data("name") 
            + " upload complete..."); 
          var img = new Image; 
          $(img).addClass(progressData.eq(-1) 
          .attr("class")); 
          img.onload = function() { 
           if (this.complete) { 
            console.log(
             progressData.data("name") 
             + " preview loading..." 
           ); 
           }; 

          }; 
         uploads.append("<br /><li>", img, "</li><br />"); 
         }; 
        } 
        return xhrUpload; 
       } 
      }) 
      .then(function (data, textStatus, jqxhr) { 
       console.log(data) 
       this.find("img[class=" + jqxhr.name + "]") 
       .attr("src", data.file) 
       .before("<span>" + data.name + "</span><br />"); 
       return data 
      }, function (jqxhr, textStatus, errorThrown) { 
       console.log(errorThrown); 
       return errorThrown 
      }); 
     }) 
    }); 
    $.when.apply(display, images).then(function() { 
     var result = $.makeArray(arguments); 
     console.log(result.length, "uploads complete"); 
    }, function err(jqxhr, textStatus, errorThrown) { 
     console.log(jqxhr, textStatus, errorThrown) 
    }) 
}; 

$(document) 
.on("change", "input[name^=file]", processFiles); 
// process `droppable` events 
droppable.ondragover = function() { 
    $(this).addClass("hover"); 
    return false; 
}; 

droppable.ondragend = function() { 
    $(this).removeClass("hover") 
    return false; 
}; 

droppable.ondrop = function (e) { 
    $(this).removeClass("hover"); 
    var image = Array.prototype.slice.call(e.dataTransfer.files) 
     .every(function (img, i) { 
     return /^image/.test(img.type) 
    }); 
    e.preventDefault(); 
    // if `file`, file type `image` , process `file` 
    if (!!e.dataTransfer.files.length && image) { 
      $(this).find(".drop-area-label") 
      .css("color", "blue") 
      .html(function (i, html) { 
      $(this).delay(3000, "msg").queue("msg", function() { 
       $(this).css("color", "initial").html(html) 
      }).dequeue("msg"); 
      return "File dropped, processing file upload..."; 
     }); 
     processFiles(e); 
    } else { 
      // if dropped `file` _not_ `image` 
      $(this) 
      .removeClass("hover") 
      .addClass("err") 
      .find(".drop-area-label") 
      .css("color", "darkred") 
      .html(function (i, html) { 
      $(this).delay(3000, "msg").queue("msg", function() { 
       $(this).css("color", "initial").html(html) 
       .parent("#drop").removeClass("err") 
      }).dequeue("msg"); 
      return "Please drop image file..."; 
     }); 
    }; 
}; 

php

<?php 
    if (isset($_POST["file"])) { 
    // do php stuff 
    // call `json_encode` on `file` object 
    $file = json_encode($_POST["file"]); 
    // return `file` as `json` string 
    echo $file; 
    }; 

jsfiddle http://jsfiddle.net/guest271314/0hm09yqo/

+0

DZIĘKUJĘ! –

+0

Pytanie, w PHP, ciąg '$ file' używam do obsługi danych i czy mogę wgrać tak jak z' $ _FILE [] '? –

+0

@ IvijanStefanStipić Serdecznie zapraszamy :) '$ plik' w' php' porcji na post _nie tak samo jak '$ _FILES'. '$ _FILES' wydaje się wymagać'

'elementu, z' enctype = "multipart/form-data" 'atrybut. Approach at post wykorzystuje typ danych 'JSON' do wysyłania, przetwarzania odpowiedzi. Zobacz http://php.net/manual/en/features.file-upload.post-method.php, http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2 , http://www.sitepoint.com/handle-file-uploads-php/, http://stackoverflow.com/questions/3586919/why-would-files-be-empty-when-uploading-files-to- php. – guest271314

5

użyłem do pracy z tej wtyczki: https://blueimp.github.io/jQuery-File-Upload/

on idealny do tego.

+0

Tak, to jest świetna wtyczka, ale chciałem uniknąć garstki bibliotek, a od strony projektowania chciałem przycisk, który zaakceptuje przeciąganie i upuszczanie i automatycznie przesłać obraz. –

Powiązane problemy