简体   繁体   English

AJAX / Laravel多个文件上传

[英]AJAX/Laravel Multiple File Uploads

I'm trying to upload multiple files from a drag/drop event using jQuery/AJAX/Laravel. 我正在尝试使用jQuery / AJAX / Laravel从拖放事件中上传多个文件。

MY DROP EVENT: 我的下降事件:

$( document ).on('drop dragleave', '.file-drag', function(e){
    $(this).removeClass('drop-ready');
    if(e.originalEvent.dataTransfer.files.length) {
      e.preventDefault();
      e.stopPropagation();

      if (e.type === "drop") {
      var files = e.originalEvent.dataTransfer.files;
      AjaxFileUpload(files)
      }
    }
  });

MY UPLOAD SCRIPT: 我的上传脚本:

function AjaxFileUpload(files){
    console.log(files);

    //Start appending the files to the FormData object.
    var formData = new FormData;
    formData.append('_token', CSRF_TOKEN);
    for(var i = 0; i < files.length; i++){
      formData.append(files[i].name, files[i])
    }

    console.log(formData.entries());

    $.ajax({
        //Server script/controller to process the upload
        url: 'upload',
        type: 'POST',

        // Form data
        data: formData,

        // Tell jQuery not to process data or worry about content-type
        // You *must* include these options!
        cache: false,
        contentType: false,
        processData: false,
        // Error logging
        error: function(jqXHR, textStatus, errorThrown){
          console.log(JSON.stringify(jqXHR));
          console.log('AJAX Error: ' + textStatus + ": " + errorThrown);
        },
        // 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;
        },
        success: function(data){
          console.log(data);
        }
    });
  }

MY CONTROLLER CODE: 我的控制器代码:

class UploadsController extends Controller
{
    public function UploadFiles(Request $request){
      return $request->all();
    }
}

I THINK my images are getting to the server side, as when I return the request object, I get the following in console: 我认为我的图像正在到达服务器端,因为当我返回请求对象时,在控制台中得到了以下内容:

在此处输入图片说明

Thus, the CSRF token is getting through, and the images (I think?) are getting through. 因此,CSRF令牌通过了,图像(我认为是)通过了。 My problem from here is accessing the files with PHP and storing them via ->store();. 我这里的问题是使用PHP访问文件并通过-> store();存储它们。

In the countless examples online/documentation, they typically use something along the lines of: 在无数在线/文档示例中,它们通常使用以下方式:

$path = $request->photo->store('images');

However, I don't understand the 'photo' aspect of this. 但是,我不了解这种“照片”方面。 What if a video or a PDF is uploaded? 如果上传了视频或PDF,该怎么办? I basically don't understand how I am to access the different parts of the request object. 我基本上不了解如何访问请求对象的不同部分。 Documentation on Laravel site is pretty sparse for this and only gives an example using 'photo' of which it never explains. Laravel网站上的文档对此非常稀疏,仅提供了一个使用“照片”的示例,但从未说明。

Figured it out. 弄清楚了。

In my uploadscontroller: 在我的uploadscontroller中:

class UploadsController extends Controller
{
    public function UploadFiles(Request $request){
      $arr = [];
      foreach($request->all() as $file){
        if(is_file($file)){
          $string = str_random(16);
          $ext = $file->guessExtension();
          $file_name = $string . '.' .  $ext;
          $filepath = 'uploads/' . Auth::user()->username . '/' . $file_name;
          $file->storeAs(('uploads/' . Auth::user()->username), $file_name);
          array_push($arr, [$file_name, $filepath]);
        }

      }
      return $arr;
    }
}

Regarding the examples found in Laravel's documentation, 'photo' is simply making use of a magic method to reference a file uploaded with a name of 'photo'. 关于Laravel文档中的示例,“照片”只是利用一种魔术方法来引用以“照片”为名称上传的文件。 You can replace 'photo' with whatever your specific file names is/are. 您可以使用任何特定的文件名替换“照片”。 Specific functions capable of being called on your uploaded files can be found here . 可以在上传的文件上调用的特定功能可以在此处找到。

This took me a while but I finally got a working solution. 这花了我一段时间,但终于有了一个可行的解决方案。 I'm using Dropzone so the list of file objects is returned by getAcceptedFiles() but it should be the same concept for you. 我正在使用Dropzone,因此文件对象的列表由getAcceptedFiles()返回,但对您来说应该是相同的概念。 I'm also attaching the files to an existing form. 我还将文件附加到现有表单上。

Upload: 上载:

var formElement = document.getElementById("addForm");
var formData = new FormData(formElement);
// Attach uploaded files to form submission
var files = myDZ.getAcceptedFiles();  // using Dropzone
for (var i = files.length - 1; i >= 0; i--) {
    formData.append('files[]', files[i]);
}

$.ajax({
    url: 'home/',
    data: formData,
    processData: false,
    contentType: false,
    timeout: 1000,
    type: 'POST',
    headers: {
        'X-CSRF-TOKEN': Laravel.csrfToken,
    },
    success: function(){
       ...
    },
    error: function (jqXHR, textStatus) {
      ...
    }
});

Controller: 控制器:

foreach($request->only('files') as $files){
    foreach ($files as $file) {
        if(is_file($file)) {    // not sure this is needed
            $fname = $file->getClientOriginalName();
            $fpath = $file->store('docs'); // path to file
        }
    }
}

Dropzone Script: Dropzone脚本:

Dropzone.autoDiscover = false;

var myDZ = new Dropzone("#my-dropzone", {
    url: "/home/files",
    maxFilesize: 5,
    maxFiles: 5,
    addRemoveLinks: true,
    dictDefaultMessage: 'Drop files here or click to upload <br> (max: 5 files)',
    headers: {
        'X-CSRF-TOKEN': Laravel.csrfToken
    },
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM