【问题标题】:Non-ajax post using Dropzone.js使用 Dropzone.js 的非 ajax 帖子
【发布时间】:2014-07-06 03:10:53
【问题描述】:

我想知道是否有任何方法可以使 Dropzone.js (http://dropzonejs.com) 与标准浏览器 POST 而不是 AJAX 一起工作。

在提交之前将输入 type=file 注入 DOM 的某种方式可能吗?

【问题讨论】:

标签: javascript html post drag-and-drop dropzone.js


【解决方案1】:

没有。出于安全原因,您不能手动设置 <input type='file'> 的值。当您使用 Javascript 拖放功能时,您完全超越了文件输入。从用户的计算机中获取文件后,将文件提交到服务器的唯一方法是通过 AJAX。

解决方法:您可以改为序列化文件或以其他方式对其进行字符串化并将其作为字符串附加到表单中,然后在服务器端对其进行反序列化。

var base64Image;
var reader  = new FileReader();
reader.addEventListener("load", function () {
    base64Image = reader.result;
    // append the base64 encoded image to a form and submit
}, false);
reader.readAsDataURL(file);

也许您使用 dropzone.js 是因为文件输入很难看且难以设置样式?如果是这种情况,这个Dropzone.js alternative 可能对你有用。它允许您创建可以与表单一起提交的自定义样式输入。它也支持拖放,但是通过拖放,您无法以您想要的方式提交表单。 免责声明:我是上述库的作者

【讨论】:

    【解决方案2】:

    所以,如果我理解正确,您想在提交您的已激活 dropzone 的表单之前附加一些数据(输入 = 文件),对吗?

    如果是这样,我必须做几乎相同的事情,我通过监听事件得到它。如果你只上传一个文件,你应该听“sending”事件,但如果你想启用多个上传,你应该听“sendingmultiple”。这是我用来完成这项工作的一段代码:

    Dropzone.options.myAwesomeForm = {
      acceptedFiles: "image/*",
      autoProcessQueue: false,
      uploadMultiple: true,
      parallelUploads: 100,
      maxFiles: 100,
    
      init: function() {
        var myDropzone = this;
    
        [..some code..]
    
        this.on("sendingmultiple", function(files, xhr, formData) {
          var attaches = $("input[type=file]").filter(function (){
            return this.files.length > 0;
          });
    
          var numAttaches = attaches.length;
    
          if( numAttaches > 0 ) {
            for(var i = 0; i < numAttaches; i++){  
              formData.append(attaches[i].name, attaches[i].files[0]);
              $(attaches[i]).remove();
            }
          }
        });
    
        [..some more code..]
    
      }
    }
    

    就是这样。希望对您有所帮助:)

    PS:如果有任何语法错误,但英语不是我的母语,请见谅

    【讨论】:

    • 这似乎并没有停止 ajax 调用......你的用例是什么?
    • 它不会停止 ajax 调用,但您可以根据需要添加其他 input=file 字段以配合您的 dropzone 表单。我的情况是我需要通过 input=file 发送 PDF 文件(不使用 dropzone)和通过 dropzone 发送图像(可以发送或不发送)。如果我的用户没有发送任何图像,我的表单将通过 POST 正常发送,但如果添加了任何图像,它将通过不允许发送 PDF 文件的 AJAX 发送。所以我不得不这样做。我以为会是你的情况。
    • 我明白了。那不是我需要的。我想为 UI 使用 dropzone,但实际上提交的表单就像使用 input=file 一样,而不是让 dropzone 进行 ajax 调用。
    • @MZAweb ,您找到解决方案了吗?
    • 不,我没有。我只是改变了我的方法,使它与 AJAX 调用一起工作。 Sill 很想找到解决方案。
    【解决方案3】:

    对于未来的访客 我已将此添加到 dropzone 选项中:

    addedfile: function (file) {
                var _this = this,
                        attachmentsInputContainer = $('#attachment_images');
                file.previewElement = Dropzone.createElement(this.options.previewTemplate);
                file.previewTemplate = file.previewElement;
                this.previewsContainer.appendChild(file.previewElement);
                file.previewElement.querySelector("[data-dz-name]").textContent = file.name;
                file.previewElement.querySelector("[data-dz-size]").innerHTML = this.filesize(file.size);
                if (this.options.addRemoveLinks) {
                    file._removeLink = Dropzone.createElement("<a class=\"dz-remove\" href=\"javascript:undefined;\">" + this.options.dictRemoveFile + "</a>");
                    file._removeLink.addEventListener("click", function (e) {
                        e.preventDefault();
                        e.stopPropagation();
                        if (file.status === Dropzone.UPLOADING) {
                            return Dropzone.confirm(_this.options.dictCancelUploadConfirmation, function () {
                                return _this.removeFile(file);
                            });
                        } else {
                            if (_this.options.dictRemoveFileConfirmation) {
                                return Dropzone.confirm(_this.options.dictRemoveFileConfirmation, function () {
                                    return _this.removeFile(file);
                                });
                            } else {
                                return _this.removeFile(file);
                            }
                        }
                    });
                    file.previewElement.appendChild(file._removeLink);
                }
                attachmentsInputContainer.find('input').remove();
                attachmentsInputContainer.append(Dropzone.instances[0].hiddenFileInput).find('input').attr('name', 'files');
                return this._updateMaxFilesReachedClass();
            },
    

    这是 dropzone 的 addedfile 选项的默认实现,包含 3 次插入。

    声明的变量attachmentsInputContainer。这是隐形方块。像

    <div id="attachment_images" style="display:none;"></div>
    

    我在这里存储带有所选图像的未来输入 然后在函数末尾从块中删除先前添加的输入(如果有)并添加新的

    attachmentsInputContainer.find('input').remove();
    attachmentsInputContainer.append(Dropzone.instances[0].hiddenFileInput).find('input').attr('name', 'files');
    

    现在,当您通过简单的提交按钮发送表单时,将发送带有值的 input[name="files"]

    我做了这个 hack 因为我将文件附加到可能尚未创建的帖子

    【讨论】:

    • 这看起来很有希望,但是当我尝试它时,添加到attachmentsInputContainer 的输入似乎在处理setupHiddenFileInput 函数时被删除了。
    • 我认为这样做的目的是使用 ajax 上传文件,然后以常规形式发送文件名。如果是这样,很酷,但这不是问题所在。 op 想要将文件追加到表单中,这是不可能的。
    【解决方案4】:

    这是我在过去的项目中使用的,

    function makeDroppable(element, callback) {
    
    var input = document.createElement('input');
    
    input.setAttribute('type', 'file');
    
    input.setAttribute('multiple', true);
    
    input.style.display = 'none';
    
    input.addEventListener('change', triggerCallback);
    
    element.appendChild(input);
    
    element.addEventListener('dragover', function(e) {
    
    e.preventDefault();
    
    e.stopPropagation();
    
    element.classList.add('dragover');
    });
    
    element.addEventListener('dragleave', function(e) {
    
    e.preventDefault();
    
    e.stopPropagation();
    
    element.classList.remove('dragover');
    });
    
    element.addEventListener('drop', function(e) {
    
    e.preventDefault();
    
    e.stopPropagation();
    
    element.classList.remove('dragover');
    
    triggerCallback(e);
    });
    
    element.addEventListener('click', function() {
    input.value = null;
    input.click();
    });
    
    function triggerCallback(e) {
    
      var files;
    
      if(e.dataTransfer) {
    
      files = e.dataTransfer.files;
    
    } else if(e.target) {
    
      files = e.target.files;
    }
    callback.call(null, files);
    }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-17
      • 2014-12-15
      • 1970-01-01
      • 1970-01-01
      • 2011-06-23
      • 1970-01-01
      • 2013-03-03
      相关资源
      最近更新 更多