使用Dropzone.js上传BLOB / ArrayBuffer

时间:2015-01-27 19:07:25

标签: rest sharepoint binaryfiles 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和上面的方法将文件转换为arraybuffer,我已成功将内容上传到SharePoint文档库,而不会损坏它们。现在,我想做同样的事情,但不必省略Dropzone.js的使用,这为功能的界面增添了一个非常好的触感。

我已经考虑修改uploadFiles()中的dropzone.js - 方法,但这似乎很激烈。我还试图弄清楚我是否可以使用accept中的options选项,但这似乎是一个死胡同。

解决方案中两个最相似的问题是下面链接的问题,其中第一个似乎适用于我的情况,但同时看起来不像我想要的那样“干净”。

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

1 - Simulating XHR to get ArrayBuffer

2 - Upload image as Base64 with Dropzone.js

所以我的问题是,在添加文件时,如何拦截它,如何将数据转换为数据缓冲区,然后使用Dropzone.js进行POST?

2 个答案:

答案 0 :(得分:3)

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

我们保留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参数传递。

答案 1 :(得分:0)

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

我设法通过猴子修补Dropzone.prototype.submitRequest()方法修改它以使用我自己的getArrayBuffer方法来修正SharePoint / Office 365的上传过程,该方法使用FileReader API返回ArrayBuffer,然后通过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”事件来使用元数据更新文件。