上传的 couchDB 附件的长度始终为 0 字节

Length of uploaded couchDB attachment always 0 Bytes

所以...我是所有这些东西的新手,我正在使用 AngularJS 和 Ionic Framework 为 android 开发一个应用程序,并尝试上传我用像这样的 cordova 捕获插件:

// gets called from scope
$scope.captureAudio = function() {
    var options = { limit: 1, duration: 10 };

    $cordovaCapture.captureAudio(options).then(function(audioData) {
        uploadFile(documentID, audioData);

    }, function(err) {
        console.log('error code: ' + err);
    });
};


var uploadFile = function (document, file) {
    var baseUrl = 'urltomydatabase';
    var name = encodeURIComponent'test.3gpp'),
        type = file[0].type,
        fileReader = new FileReader(),
        putRequest = new XMLHttpRequest();

    $http.get(baseUrl + encodeURIComponent(document))
        .success(function (data) {
            putRequest.open('PUT', baseUrl + encodeURIComponent(document) + '/' + name + '?rev=' + data._rev, true);
            putRequest.setRequestHeader('Content-Type', type);

            fileReader.readAsArrayBuffer(file[0]);
            fileReader.onload = function (readerEvent) {
                putRequest.send(readerEvent);
            };

            putRequest.onreadystatechange = function (response) {
                if (putRequest.readyState == 4) {
                    //success - be happy
                }
            };
        })
        .error(function () {
          // failure
        });
};

文件在 console.log 中的外观:

在设备上播放录制的文件效果很好。 但是每次我上传录音并且上传完成时,文档中上传的附件在 couchDB 中的长度为“0”。

上传后创建的文件在数据库中的外观:

我做错了什么?

编辑: 我刚刚发现,当我上传图像时,从这个函数作为 blob 传递,效果很好:

function upload(imageURL) {
    var image = new Image();
    var onload = function () {
        var canvas = document.createElement("canvas");
        canvas.width = this.width;
        canvas.height = this.height;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(this, 0, 0);
        canvas.toBlob(function (blob) {
            uploadFile(documentID, blob);
        });
    };
    image.onload = onload;
    image.src = imageURL;
}

也许解决方案是从音频文件中创建一个 blob?但是每次我尝试它时,我的 blob 甚至在上传之前的大小都是 0 字节,而且我没有找到关于如何将 MediaFile 对象转换为 blob 的很好的解释...

您的代码似乎没有将文件内容作为多部分附件发送。要查看真正发送到 couchdb 的内容,请使用 wireshark (https://www.wireshark.org/) 等捕获流量。

This thread 给我带来了解决方案,PouchDB 净化了它。现在我的上传功能看起来像这样并且可以处理所有文件格式

// e.g capture Audio
$scope.captureAudio = function () {
    var options = {limit: 1, duration: 10};
    $cordovaCapture.captureAudio(options).then(function (audioData) {
        uploadFile(documentID, audioData, 'audio');
    }, function (err) {
        console.log('error code: ' + err);
    });
};

 var uploadFile = function (id, file, mediatype) {

        var fileName = makeID();
        if (mediatype == 'image') var name = encodeURIComponent(fileName + '.jpg');
        if (mediatype == 'audio') var name = encodeURIComponent(fileName + '.3gpp');
        if (mediatype == 'video') var name = encodeURIComponent(fileName + '.3gp');

        db.get(id).then(function (doc) {
            var path = file.fullPath;
            window.resolveLocalFileSystemURL(path, function (fileEntry) {
                return fileEntry.file(function (data) {
                    var reader = new FileReader();
                    reader.onloadend = function (e) {
                        var blob = b64toBlobAlt(e.target.result, file.type);
                        if (blob) {
                            db.putAttachment(id, name, doc._rev, blob, file.type).then(function () {
                                if (mediatype == 'video' || mediatype == 'image') getMedia();
                                if (mediatype == 'audio') $scope.audios.push(source);
                            });
                        }
                    };
                    return reader.readAsDataURL(data);
                });
            });
        });
    };


// creating the blob from the base64 string
function b64toBlobAlt(dataURI, contentType) {
    var ab, byteString, i, ia;
    byteString = atob(dataURI.split(',')[1]);
    ab = new ArrayBuffer(byteString.length);
    ia = new Uint8Array(ab);
    i = 0;
    while (i < byteString.length) {
        ia[i] = byteString.charCodeAt(i);
        i++;
    }
    return new Blob([ab], {
        type: contentType
    });
}