正在上传 BLOB/ArrayBuffer 和 Dropzone.js

Uploading BLOB/ArrayBuffer with Dropzone.js

使用 SharePoint 2013 REST API,我使用 Dropzone.js 成功地将 .docx.png 等文件上传到文档库中的文件夹.我有一个函数,我按如下方式初始化我的 dropzone:

myDropzone = new Dropzone("#dropzone");

myDropzone.on("complete", function (file) {
    myDropzone.removeFile(file);
});

myDropzone.options.autoProcessQueue = false;

myDropzone.on("addedfile", function (file) {
    $('.dz-message').hide();
    myDropzone.options.url = String.format(
    "{0}/{1}/_api/web/getfolderbyserverrelativeurl('{2}')/files" +
    "/add(overwrite=true, url='{3}')",
    _spPageContextInfo.siteAbsoluteUrl, _spPageContextInfo.webServerRelativeUrl, folder.d.ServerRelativeUrl, file.name);
});

myDropzone.options.previewTemplate = $('#preview-template').html();

myDropzone.on('sending', function (file, xhr, fd) {
    xhr.setRequestHeader('X-RequestDigest', $('#__REQUESTDIGEST').val());
});

我遇到的问题是几乎所有文件(PDF 是唯一一个不是)在上传完成后都显示为损坏文件。这很可能是由于 SharePoint 要求上传的文件作为 ArrayBuffer 发送。 MSDN Source

使用常规 Ajax POST 和上述方法将文件转换为数组缓冲区,我已成功将内容上传到 SharePoint 文档库,而且它们没有损坏。现在,我想做同样的事情,但不必省略 Dropzone.js 的使用,这为功能界面增添了非常好的触感。

我研究过修改 dropzone.js 中的 uploadFiles() 方法,但这似乎很激进。我也试图弄清楚我是否可以在 options 中使用 accept 选项,但这似乎是一个死胡同。

解决方案最相似的两个问题是下面链接的问题,第一个似乎适用于我的情况,但同时 "clean" 看起来比我想使用的要少。

第二个用于上传带有 Base64 编码的图像。

2 - Upload image as Base64 with Dropzone.js

所以我的问题简而言之就是,当添加一个文件时,我如何拦截它,将数据转换为数组缓冲区,然后使用 Dropzone.js POST 它?

这是对我自己的问题的迟到回答,但这是我们最终寻求的解决方案。

我们保留 dropzone.js 只是为了漂亮的界面和一些帮助功能,但我们决定使用 $.ajax() 进行实际的文件上传。

我们使用 HTML5 FileReader

将文件作为数组缓冲区读取
var reader = new FileReader();
reader.onloadend = function(e) {
    resolve(e.target.result);
};
reader.onerror = function(e) {
    reject(e.target.error);
};
reader.readAsArrayBuffer(file);

然后将其作为 ajax 选项中的 data 参数传递。

我最近遇到了这个确切的问题,因此对 Dropzone 库进行了一些调查。

我设法更正了 SharePoint/Office 365 的上传过程,方法是通过猴子修补 Dropzone.prototype.submitRequest() 方法来修改它以使用我自己的 getArrayBuffer 方法,returns ArrayBuffer 使用FileReader API,然后通过 Dropzone 生成的 XMLHttpRequest 发送它。

这使我能够继续使用 Dropzone API 的功能。

仅在单个自动上传上进行了测试,因此需要进一步调查多文件上传。

猴子补丁

Dropzone.prototype.submitRequest = function (xhr, formData, files) {
    getArrayBuffer(files[0]).then(function (buffer) {
        return xhr.send(buffer);
    });
};

getArrayBuffer

function getArrayBuffer(file) {
    return new Promise(function (resolve, reject) {
        var reader = new FileReader();

        reader.onloadend = function (e) {
            resolve(e.target.result);
        };
        reader.onerror = function (e) {
            reject(e.target.error);
        };
        reader.readAsArrayBuffer(file);
    });
}

文件上传到 SharePoint 后,我​​使用 Dropzone 'success' 事件用元数据更新文件。