Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用xmlhttprequest获取跨域PNG文件_Javascript_Image_Xmlhttprequest_Cross Domain - Fatal编程技术网

Javascript 使用xmlhttprequest获取跨域PNG文件

Javascript 使用xmlhttprequest获取跨域PNG文件,javascript,image,xmlhttprequest,cross-domain,Javascript,Image,Xmlhttprequest,Cross Domain,可悲的是,我看到了无数类似的问题,但似乎没有针对我的情况的答案。我没有使用jquery。我只关心最新的浏览器(尤其是Chrome)。我正在寻找一种从跨域获取PNG或JPG文件加载javascript图像的方法 i、 e.我只想这样做: var img1 = new Image(); img1.addEventListener('load', function() { imageLoaded( canvas, context, this); }, false) img1.src = texture

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

i、 e.我只想这样做:

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>
var img3=新图像();
var req=new window.XMLHttpRequest();
req.overrideMimeType('text/plain;charset=x-user-defined');//似乎没什么区别
req.responseType='arraybuffer';//与arraybuffer或blob一起没有乐趣
请求打开(“GET”,textureUrl,true,”,“);//异步请求允许CORS飞行前交换
req.onreadystatechange=功能(oEvent){
如果(req.readyState==4){
如果(请求状态===200){
警报(“XHR工作”);
如果(请求响应){
警报(“resp text:+req.response);//将响应标识为arraybuffer或blob
}
//我相信这是我最需要帮助的地方。
//var base64Img=window.btoa(unescape(encodeURIComponent(req.responseText));
var base64Img=window.btoa(unescape(encodeURIComponent(req.response));
警报(“b64:+base64Img);//模糊地为uu64ish,但被截断
var src=“”;
if(isPng==1){//只是为了表明src url是为jpg构建的。
警报(“png”);
src='data:image/png;base64'+base64Img;
} 
....
img3.src=src;//如果我在这里阻塞同一个域url,则img3的加载很好
从我所读到的内容来看,如果我指定arraybuffer,我不清楚是否需要重写mime类型,但我不清楚

我得到了数据(没有跨域错误,耶),它似乎大小合适,但我不相信我成功地对它进行了uu64编码,也不相信我在图像中插入了合适的数据url

再说一次,我只需要在最新的Chrome浏览器上使用它,我希望尽可能做到“纯HTML5”,所以我觉得没有必要使用IE7等等

我不知道req.response是否包含HTTP响应的第一行(即,我是否有责任在UU编码之前对其进行修剪…)

希望你能从我的眼睛里拔出毛线


提前谢谢。

我在同一个问题上被困了一段时间。这就是你需要做的,以使它工作:

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

req.responseType='arraybuffer';
棘手的事情是在
arraybuffer
的情况下,
req.responseText
不起作用,而是使用
req.response

var base64Img=window.btoa(
景观(
编码器组件(请求响应)
)
);

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

使用获取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);
    });
  }
//Lang:Typescript
专用异步转换器BlobToBase64(blob:blob):承诺{
返回新承诺((解决、拒绝)=>{
const reader=new FileReader();
reader.onerror=拒绝;
reader.onload=()=>{
解析(reader.result为字符串);
};
reader.readAsDataURL(blob);
});
}

OK,看起来这里毕竟有一篇相关文章。我上面的错误是:嘿,一行注释。OK..首先..非常确定我不需要OverrideMetype。将responsetype设置为'arraybuffer'很好,但是返回的数组缓冲区是通过req.response访问的,而不是通过req.responseText(duh)最后,我使用了一些发布在这里的代码(对于这个注释来说太大了)对数据进行uuencode,并使用data:uri来设置图像源。这样就可以了。XHR处理CORS预飞行(设置请求源标头,这使正确配置的服务器能够返回跨域图像,而不会污染画布)是的。相关文章的链接?@user1005997如果你以答案的形式发表评论,并选择它作为答案,你可以将其格式设置得更好,并有可能获得更多选票。在这里可以合理地回答你自己的问题。非常感谢。我几乎放弃了:)