【问题标题】:XHR + data URI doesn't work in SafariXHR + 数据 URI 在 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 中运行?

【问题讨论】:

  • 你解决了吗?我面临着完全相同的问题
  • 这里也面临同样的问题。很想知道你是否能够解决这个问题。

标签: javascript safari xmlhttprequest


【解决方案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,因为他们有消息传递开销)。
猜你喜欢
  • 2015-11-22
  • 1970-01-01
  • 2015-07-30
  • 2011-12-23
  • 2014-03-24
  • 1970-01-01
  • 2018-01-06
  • 2019-01-08
  • 2019-07-12
相关资源
最近更新 更多