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

时间:2015-07-30 18:20:42

标签: javascript android angularjs cordova couchdb

所以...我是所有这些东西的新手,我正在使用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中的显示方式:

enter image description here

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

上传后,创建的文件在数据库中的显示方式:

enter image description here

我做错了什么?

编辑:我刚刚发现,当我上传图片时,从此函数传递为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;
}

所以也许解决方案是从audiofile创建一个blob?但每次我尝试它,我的blob甚至在上传前都有0字节的大小,我没有找到一个很好的解释如何将MediaFile对象转换为blob ......

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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
    });
}