如何使用 dropzone 上传 base64 图像资源?

Posted

技术标签:

【中文标题】如何使用 dropzone 上传 base64 图像资源?【英文标题】:How to upload base64 image resource with dropzone? 【发布时间】:2014-04-01 12:13:55 【问题描述】:

我正在尝试使用Dropzone.js 上传生成的客户端文档(暂时的图像)。

// .../init.js

var myDropzone = new Dropzone("form.dropzone", 
    autoProcessQueue: true
); 

一旦客户完成了他的工作,他只需点击一个调用保存功能的保存按钮:

// .../save.js

function save(myDocument) 

    var file =  
        name: 'Test',
        src: myDocument,
    ;

    console.log(myDocument);

    myDropzone.addFile(file);

console.log() 正确返回我的文档内容

 data:image/png;base64,iVBORw0KGgoAAAANS...

此时,我们可以在拖放区看到上传文档的进度条,但是上传失败。

这是我的(标准 dropzone)html 表单:

<form action="/upload" enctype="multipart/form-data" method="post" class="dropzone">
    <div class="dz-default dz-message"><span>Drop files here to upload</span></div>
    <div class="fallback">
        <input name="file" type="file" />
    </div>
</form>

我有一个接收发布请求的 Symfony2 控制器。

// Get request
$request = $this->get('request'); 

// Get files
$files = $request->files;

// Upload
$do = $service->upload($files);

从 dropzone 上传(通过拖放或单击)正在工作并且上传成功,但使用 myDropzone.addFile() 函数在我的控制器中返回一个空对象:

var_dump($files);

返回

object(Symfony\Component\HttpFoundation\FileBag)#11 (1) 
  ["parameters":protected]=>
  array(0) 
  

我认为我没有在保存功能中正确设置我的 var 文件。 我尝试创建 JS 图像(var img = new Image() ...)但没有任何成功。

感谢您的帮助!

【问题讨论】:

看看这个包:github.com/1up-lab/OneupUploaderBundle。它解决了您遇到的问题以及您将来可能遇到的许多其他问题。 对不起,但不。我的 dropzone 是作为我的控制器和动作的功能。是 addFile 函数的使用不起作用,因为我使用包含图像源的输入(在 js 中动态创建)并且我不知道如何将其转换为被 addFile 函数接受。 【参考方案1】:

最后我找到了一个不创建画布的可行解决方案:

function dataURItoBlob(dataURI) 
    'use strict'
    var byteString, 
        mimestring 

    if(dataURI.split(',')[0].indexOf('base64') !== -1 ) 
        byteString = atob(dataURI.split(',')[1])
     else 
        byteString = decodeURI(dataURI.split(',')[1])
    

    mimestring = dataURI.split(',')[0].split(':')[1].split(';')[0]

    var content = new Array();
    for (var i = 0; i < byteString.length; i++) 
        content[i] = byteString.charCodeAt(i)
    

    return new Blob([new Uint8Array(content)], type: mimestring);

还有保存功能:

function save(dataURI) 

    var blob = dataURItoBlob(dataURI);
    myDropzone.addFile(blob);


文件在 dropzone 中正确显示并成功上传。 我仍然需要处理文件名(我的文档名为“blob”)。

dataURItoBlob 函数在这里找到:Convert Data URI to File then append to FormData

[EDIT]:我终于在 dropzone 中编写了函数来完成这项工作。你可以在这里查看:https://github.com/CasperArGh/dropzone 你可以像这样使用它:

var dataURI = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAmAAAAKwCAYAAA...';
myDropzone.addBlob(dataURI, 'test.png');

【讨论】:

只需在addFile(blob); 之前添加blob.name='quirks'; 即可为我添加文件名。谢谢 你应该在官方仓库为你提出一个 PR addBlob 方法。 你也可以使用 filer.js for datauri to blob:github.com/ebidel/filer.js/blob/master/src/filer.js#L137【参考方案2】:

我目前无法发表评论,想将其发送给您。

我知道你找到了答案,但我在使用你的 Git 代码时遇到了一些问题,并根据我的需要对其进行了一些调整,但我大约 100% 肯定这将适用于添加文件或 blob 或任何东西,并能够为其应用名称。

Dropzone.prototype.addFileName = function(file, name) 
    file.name = name;
  file.upload = 
    progress: 0,
    total: file.size,
    bytesSent: 0
  ;
  this.files.push(file);
  file.status = Dropzone.ADDED;
  this.emit("addedfile", file);
  this._enqueueThumbnail(file);
  return this.accept(file, (function(_this) 
    return function(error) 
      if (error) 
        file.accepted = false;
        _this._errorProcessing([file], error);
       else 
        file.accepted = true;
        if (_this.options.autoQueue) 
          _this.enqueueFile(file);
        
      
      return _this._updateMaxFilesReachedClass();
    ;
  )(this));
;

如果将其添加到 dropzone.js(我在 Dropzone.prototype.addFile = function(file) 的行下方做了可能是 1110 的行。

像魅力一样工作,使用起来和其他任何东西一样。 myDropzone.addFileName(file,name)!

希望有人觉得这很有用,不需要重新创建它!

【讨论】:

在有人问我之前,我已经从截图中粘贴了 blob(目前仅在 IE 上),但没有尝试使用它来上传其他类型的文件。【参考方案3】:

1) 你说:“一旦客户完成了他的工作,他只需要点击一个调用保存函数的保存按钮:”

这意味着您设置autoProcessQueue: false 并拦截按钮单击,以执行saveFile() 函数。

$("#submitButton").click(function(e) 
    // let the event not bubble up
    e.preventDefault();
    e.stopPropagation();
    // process the uploads
    myDropzone.processQueue();
);

2) 检查表单操作

检查您的表单 action="/upload" 是否已正确路由到您的 SF 控制器和操作。

3) 示例代码

您可以在官方 Wiki

上找到完整的示例

4) 好的,感谢您的 cmets,我更好地理解了这个问题:

“如何使用 dropzone 保存我的 base64 图像资源?”

需要将图片内容作为值嵌入

// base64 data
var dataURL = canvas.toDataURL();

// insert the data into the form
document.getElementById('image').value = canvas.toDataURL('image/png');
//or jQ: $('#img').val(canvas.toDataURL("image/png"));

// trigger submit of the form
document.forms["form1"].submit();
您可能会遇到麻烦,可能需要将“origin-clean”标志设置为“true”。见http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#security-with-canvas-elements how to save html5 canvas to server

【讨论】:

感谢您的回复。 1) 2) 1) autoProcessQueue 当前为“真”。我有一个独特的 dropzone,允许用户拖放/单击上传,还有一个编辑器来创建新图像。我需要 autoProcessQueue 为“true”:创建新图像应将创建的文件推送到队列中,如果没有更多作业,则会立即上传。 2) 正如我所说:从 dropzone 上传(通过拖放或单击)正在工作并且上传成功,因此我的路由/控制器/操作配置正确。仅使用 javascript 函数 myDropzone.addFile() 在我的控制器中返回一个空对象。 3) 这个例子对我没有帮助:)。我的主要问题是我应该将什么样的对象传递给 addFile() 函数,因为我有一个字符串作为图像源 addFile() 接受文件名github.com/enyo/dropzone/blob/master/lib/dropzone.js#L805 你拥有的是一个图像资源字符串。

以上是关于如何使用 dropzone 上传 base64 图像资源?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 react-dropzone 中将图像转换为 base64?

如何从 dropzone.js 上传和删除文件

图片预览 base64 element 图片上传 预览图

如何使用 Dropzone.js 进行分块文件上传(仅限 PHP)?

Dropzone 跨平台缩略图生成

markdown 如何使用dropzone js上传文件