2

可悲的是,我看到无数类似的问题,但没有针对我的具体情况的答案。我没有使用 jquery。除了最新的浏览器(尤其是 Chrome),我什么都不关心。我正在寻找一种从 PNG 或 JPG 文件的跨域获取中加载 javascript 图像的方法。

即我只想这样做:

var img1 = new Image();
img1.addEventListener('load', function() { imageLoaded( canvas, context, this); }, false)
img1.src = textureUrl;

这适用于同一个域。但是,显然这不会在请求标头中包含 Origin 标签,因此即使我们已经在服务器上成功设置了 CORS 标头,它也无法在跨域环境中工作。如果我可以对此请求执行一些简单的操作以包含该标头,那就太好了。

但我收集到我必须做的是使用 XHR 对资产进行异步获取,获取二进制数据,然后以某种方式将该数据推送到常规 Image() 对象中。我相信我们已经成功地获得了各种形式的数据(尝试了arraybuffer和blob),但没有成功将其干扰到Image()对象中。

例如:

var img3 = new Image();
var req = new window.XMLHttpRequest();
req.overrideMimeType('text/plain; charset=x-user-defined');  // seems to make no difference
req.responseType = 'arraybuffer';  // no joy with arraybuffer or blob
req.open("GET", textureUrl, true, "", "");  // async request allows CORS preflight exchange

req.onreadystatechange = function (oEvent) {
  if (req.readyState === 4) {
    if (req.status === 200) {
        alert( "XHR worked" );
        if( req.response ) {
          alert( "resp text: " + req.response );  // identifies response as arraybuffer or blob
        }

        // I believe this section is where I need the most help.

        // var base64Img = window.btoa(unescape(encodeURIComponent( req.responseText)) );

        var base64Img = window.btoa( unescape( encodeURIComponent( req.response ) ) );
        alert( "b64: " +  base64Img );  // vaguely uu64ish, but truncated
        var src = "";
        if( isPng == 1 ) {  // just to indicate the src url is built differently for jpg.
            alert("png");
            src = 'data:image/png;base64,' + base64Img;
        } 

        ....
        img3.src = src;  // img3 loads fine if I just jam a same domain url here

  <closing braces>

从我读过的内容来看,如果我指定arraybuffer,我不清楚我是否需​​要覆盖mime类型,但我不清楚。

我取回了数据(没有跨域错误,是的),它的大小似乎是正确的,但我不相信我成功地对其进行了 uu64 编码,也不相信我正在将合适的数据 url 插入图像中。

同样,我只需要它来使用最新的 Chrome 浏览器,并且我希望尽可能“纯 HTML5”,所以我觉得不需要使用 IE7 等。

我不知道 req.response 是否包含 HTTP 响应的第一行(即我有责任在 uuencoding 之前修剪一些东西......)

希望你能把羊毛从我的眼睛里拉出来!

提前致谢。

4

2 回答 2

0

我在同一个问题上停留了一段时间。这是您需要执行的操作才能使其正常工作:

对于 zip/png 等格式,您应该使用:

req.responseType = 'arraybuffer';

棘手的事情是arraybuffer,req.responseText不起作用,而是使用req.response

var base64Img = window.btoa(
  unescape(
    encodeURIComponent(req.response)
  )
);
于 2015-08-03T10:40:04.463 回答
0

如果您对使用最新的 HTML 功能感到满意,以下内容可能会有所帮助。

使用 Fetch API 加载二进制文件:

const response = await fetch('https://cross-origin.org/path-to-binary.png' , {
  cache: 'no-cache',
  mode: 'cors',
  credentials: 'omit'
});

if (!response.ok) {
  console.error(response);
  throw new Error(response.statusText);
}

console.log('response from fetch', response);
const blob = await response.blob();

要将 Blob 转换为 base64,您可以使用 FileReader API

// Lang: Typescript
  private async convertBlobToBase64(blob: Blob): Promise<string> {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onerror = reject;
      reader.onload = () => {
        resolve(reader.result as string);
      };
      reader.readAsDataURL(blob);
    });
  }
于 2020-06-07T18:50:36.957 回答