Safari iOS 6 - ajax请求blob图像

时间:2014-06-12 13:38:36

标签: javascript ajax ember.js filereader

我有一个主要在blob对象中下载图像的功能,它在chrome,FF,iOS 7+上工作正常,但在iOS 6上没有...

downloadImage: function( url ) {
        var that = this;
        return new Ember.RSVP.Promise(function( resolve, reject ) {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url);
            xhr.onreadystatechange = function() {
                if (this.readyState === this.DONE) {
                    that.chart.incrementProgress();
                    if (this.status === 200) {
                        var blob = this.response;
                        resolve( that.imageStore.writeImage( that, url, blob ) );
                    }
                    else {
                        resolve();
                    }
                }
            };
            xhr.responseType = 'blob';
            xhr.send();

        });
    }

在控制台调试器的iOS6中,当我想看到我的blob对象时,它似乎是一个字符串中有超级奇怪的字符..我不确定它是否正常或我的请求不是'在这个版本的iOS上正常工作。

之后我需要将它转换为base64,所以我使用FileReader就是这样:

this.writeImage = function( controller, url, blob ) {
        var that = this;
        return new Ember.RSVP.Promise(function( resolve ) {
            var reader = new window.FileReader();
            reader.readAsDataURL(blob);
            reader.onloadend = function() {
                var base64 = reader.result;
                var object = { id: url, key: url, base64: base64 };
                //controller.store.update('image', object).save();
                controller.store.findQuery('image', { key: url })
                .then(function( result ) {
                    var record = result.content[0];
                    record._data.base64 = base64;
                    record.save().then( resolve );
                })
                .catch(function() {
                    controller.store.createRecord('image', object).save().then( resolve );
                });
            };
        });
    };

不要注意Promise事物和其他参数,但blob与downloadImage函数中的blob相同。

由于一个神秘的原因,reader.loadend永远不会被触发,因为读者中的状态始终为0。

我应该为iOS6做一些特别的事情,否则我的代码是错的?

[编辑]:它不像触发的onloadend回调??

[edit2]:经过进一步调查后,似乎ajax请求的响应是字符串而不是blob ...而且我的responseType也设置为""

1 个答案:

答案 0 :(得分:0)

我现在找到了一种解决方法,我将binaryString转换为这样的blob:

function binaryStringToBlob( byteCharacters, contentType ) {
    var sliceSize = 1024;
    var bytesLength = byteCharacters.length;
    var slicesCount = Math.ceil(bytesLength / sliceSize);
    var byteArrays = new Array(slicesCount);

    for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
        var begin = sliceIndex * sliceSize;
        var end = Math.min(begin + sliceSize, bytesLength);

        var bytes = new Array(end - begin);
        for (var offset = begin, i = 0 ; offset < end; ++i, ++offset) {
            bytes[i] = byteCharacters[offset].charCodeAt(0);
        }
        byteArrays[sliceIndex] = new Uint8Array(bytes);
    }
    return new Blob(byteArrays, { type: contentType });
}

您只需要获取内容类型,然后就可以了!