XHR + 数据 URI 在 Safari 中不起作用

Posted

技术标签:

【中文标题】XHR + 数据 URI 在 Safari 中不起作用【英文标题】:XHR + data URI doesn't work in Safari 【发布时间】:2015-09-04 08:51:49 【问题描述】:

我使用 XMLHttpRequest 使用此代码从数据 URI 生成 Blob

function dataUrlToBlob(dataUrl, callback) 
    var xhr = new XMLHttpRequest;
    xhr.open( 'GET',  dataUrl);
    xhr.responseType = 'arraybuffer';
    xhr.onload = function(e) 
        callback( new Blob( [this.response], type: 'image/png' ) );
    ;
    xhr.send();

用法:

dataUrlToBlob('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2NkAAIAAAoAAggA9GkAAAAASUVORK5CYII=', callback);

在除 Safari 之外的所有浏览器中一切正常。它会抛出这样的错误:

[错误] XMLHttpRequest 无法加载数据:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2NkAAIAAAoAAggA9GkAAAAASUVORK5CYII=。仅 HTTP 支持跨源请求。

问题是,有什么方法可以让这种方法在 Safari 中运行?

【问题讨论】:

你解决了吗?我面临着完全相同的问题 这里也面临同样的问题。很想知道你是否能够解决这个问题。 【参考方案1】:

您为什么要使用 XHR 来做到这一点?只需同步执行(答案来自here):

function dataURItoBlob(dataURI) 
    if(typeof dataURI !== 'string')
        throw new Error('Invalid argument: dataURI must be a string');
    
    dataURI = dataURI.split(',');
    var type = dataURI[0].split(':')[1].split(';')[0],
        byteString = atob(dataURI[1]),
        byteStringLength = byteString.length,
        arrayBuffer = new ArrayBuffer(byteStringLength),
        intArray = new Uint8Array(arrayBuffer);
    for (var i = 0; i < byteStringLength; i++) 
        intArray[i] = byteString.charCodeAt(i);
    
    return new Blob([intArray], 
        type: type
    );

【讨论】:

我知道。但是异步更快。这不是这里的问题。 @artch 一个异步函数总是比同步函数做同样的事情要慢。 请不要为此争论不休。你不知道我们的确切用例,所以它毫无意义。 XHR 能够在某些系统上并行使用多个内核,因此在许多并发操作环境中,它比使用相同的单个 JS 进程(甚至使用 Web Worker,因为他们有消息传递开销)。

以上是关于XHR + 数据 URI 在 Safari 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

表单序列化在 Safari 中不起作用?

HTML5 视频加载数据事件在 IOS Safari 中不起作用

HTML5 视频作为 base64 编码数据 URI 在 iPad 和 iPhone 浏览器中不起作用

跨域 Ajax 调用在 Safari 4 和 Safari 5 中不起作用

Flexbox 中心在 Safari 中不起作用

IFrame 在 Safari 中不起作用