【问题标题】:AJAX/Laravel Multiple File UploadsAJAX/Laravel 多文件上传
【发布时间】:2017-08-02 23:42:51
【问题描述】:

我正在尝试使用 jQuery/AJAX/Laravel 从拖放事件中上传多个文件。

我的掉落事件:

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

我的上传脚本:

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

我的控制器代码:

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

我认为我的图像正在到达服务器端,因为当我返回请求对象时,我在控制台中得到以下信息:

因此,CSRF 令牌正在通过,图像(我认为?)正在通过。我的问题是使用 PHP 访问文件并通过 ->store(); 存储它们。

在无数的在线/文档示例中,他们通常使用以下内容:

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

但是,我不明白其中的“照片”方面。如果上传了视频或 PDF 文件怎么办?我基本上不明白如何访问请求对象的不同部分。 Laravel 网站上的文档对此非常稀少,仅给出了一个使用“照片”的示例,它从未解释过。

【问题讨论】:

    标签: php jquery laravel upload


    【解决方案1】:

    想通了。

    在我的上传控制器中:

    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;
        }
    }
    

    【讨论】:

      【解决方案2】:

      这花了我一段时间,但我终于找到了一个可行的解决方案。我正在使用 Dropzone,因此文件对象列表由 getAcceptedFiles() 返回,但它对您来说应该是相同的概念。我还将这些文件附加到现有表单中。

      上传:

      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) {
            ...
          }
      });
      

      控制器:

      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 脚本:

      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
          },
      });
      

      【讨论】:

        【解决方案3】:

        关于 Laravel 文档中的示例,'photo' 只是使用一种神奇的方法来引用一个名为 'photo' 的上传文件。您可以将“照片”替换为您的特定文件名。可以在您上传的文件上调用的特定函数可以找到here

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-01-11
          • 2016-07-21
          • 1970-01-01
          • 2014-04-19
          • 2019-07-26
          • 2017-04-27
          • 1970-01-01
          相关资源
          最近更新 更多