Webgl Cross Origin Images无法正常工作 [英] Webgl Cross Origin Images don't work

查看:53
本文介绍了Webgl Cross Origin Images无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

跨域图片存在一些问题,希望您能为您提供帮助.

这是行为.我有2个域,例如:-domain1.com-domain2.com

在domain1上,我放置了许多html5游戏.该域只是游戏的存储库.

Domain2是真实的网站(wordpress网站),用户可以在其中玩domain1上托管的游戏.为此,我对每个游戏都提出了卷曲要求.

在domain1 nginx配置文件中,我放置了以下代码行以启用跨源资源共享:

位置〜* \.(ogg | ogv | svg | svgz | eot | otf | woff | mp4 | ttf | css | rss | atom | json | js | jpg | jpeg | gif | png | ico | zip | tgz | gz |rar | bz2 | doc | xls | exe | ppt | tar | mid | midi | wav | bmp | rtf | swf | mp3 | xml | woff2)$ {add_header访问控制允许来源""*";access_log关闭;log_not_found关闭;最多到期;}

这解决了许多游戏的一些问题,但是某些游戏仍然无法正常工作,并且出现了js错误:

未捕获的DOMException:无法在"WebGLRenderingContext"上执行"texImage2D":可能无法加载位于http://domain1.com/html5-games/action/candy-match/images/loadingbarbackground-sheet0.png的跨域图像.在GLWrap_.loadTexture(http://domain1.com/html5-games/action/candy-match/c2runtime.js:2618:16)在pluginProto.Type.typeProto.loadTextures(http://domain1.com/html5-games/action/candy-match/c2runtime.js:18070:46)在pluginProto.Instance.instanceProto.onCreate(http://domain1.com/html5-games/action/candy-match/c2runtime.js:18146:13)在Runtime.createInstanceFromInit(http://domain1.com/html5-games/action/candy-match/c2runtime.js:4806:8)在Layer.createInitialInstances(http://domain1.com/html5-games/action/candy-match/c2runtime.js:7541:25)在Layout.startRunning(http://domain1.com/html5-games/action/candy-match/c2runtime.js:6715:10)在Runtime.go_loading_finished(http://domain1.com/html5-games/action/candy-match/c2runtime.js:4067:36)在Runtime.go(http://domain1.com/html5-games/action/candy-match/c2runtime.js:3966:9)在http://domain1.com/html5-games/action/candy-match/c2runtime.js:4025:60

我在网上进行了一些研究,发现了类似这些的文章

第二张图片具有相同的标题,但它起作用,因为我们设置了 crossOrigin 属性

请注意,您可能可以在游戏脚本之前包含类似这样的脚本,以便在CORS支持中进行破解.

 (function(){函数isSameOrigin(url){返回(新的URL(URL,window.location.href)).origin === window.location.origin;}函数needsCORS(url){//不确定应检查的所有URL返回!isSameOrigin(url)&&!url.startsWith("blob:")&&!url.startsWith("data:");}const srcSetFn = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype,'src').set;Object.defineProperty(HTMLImageElement.prototype,'src',{枚举:是的,设置:function(url){如果(needsCORS(url)){//如果尚未设置则设置如果(this.crossOrigin!==未定义){this.crossOrigin ='';}} 别的 {this.crossOrigin =未定义;}//设置原始属性srcSetFn.call(this,url);},});}()); 

I've got some problem with cross-origin image and I hope you can help.

Here the beahviour. I've got 2 domains, in example: - domain1.com - domain2.com

On domain1 I put many html5 games. This domain is only a repository of games.

Domain2 is the real website (wordpress website) where users can play games hosted on domain1. To doing this I made a curl request for every game.

In domain1 nginx configuration file I put these lines of code for enabling Cross Origin Resource Sharing:


    location ~* \.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|json|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|swf|mp3|xml|woff2)$ {
        add_header "Access-Control-Allow-Origin" "*";
        access_log off;
        log_not_found off;
        expires max;
    }

This resolved some issues for many games but some games are still not working and I get this js error:


    Uncaught DOMException: Failed to execute 'texImage2D' on 'WebGLRenderingContext': The cross-origin image at http://domain1.com/html5-games/action/candy-match/images/loadingbarbackground-sheet0.png may not be loaded.
        at GLWrap_.loadTexture (http://domain1.com/html5-games/action/candy-match/c2runtime.js:2618:16)
        at pluginProto.Type.typeProto.loadTextures (http://domain1.com/html5-games/action/candy-match/c2runtime.js:18070:46)
        at pluginProto.Instance.instanceProto.onCreate (http://domain1.com/html5-games/action/candy-match/c2runtime.js:18146:13)
        at Runtime.createInstanceFromInit (http://domain1.com/html5-games/action/candy-match/c2runtime.js:4806:8)
        at Layer.createInitialInstances (http://domain1.com/html5-games/action/candy-match/c2runtime.js:7541:25)
        at Layout.startRunning (http://domain1.com/html5-games/action/candy-match/c2runtime.js:6715:10)
        at Runtime.go_loading_finished (http://domain1.com/html5-games/action/candy-match/c2runtime.js:4067:36)
        at Runtime.go (http://domain1.com/html5-games/action/candy-match/c2runtime.js:3966:9)
        at http://domain1.com/html5-games/action/candy-match/c2runtime.js:4025:60

I made some research online and I found articles like these https://webglfundamentals.org/webgl/lessons/webgl-cors-permission.html Drawing images to canvas with img.crossOrigin = "Anonymous" doesn't work

but they are not very helpful.

I wouldn't like to modify original game files. I'm looking for a server side solution if it exists. If not, have you got some idea for resolve my problem?

Is there some error in my configuration? Am I missing something?

Thank you for the help.

Valerio

解决方案

The games have to request cross origin images. Simply returning the correct headers is not enough. If the games themselves don't request cross origin images by setting the crossOrigin attribute then the browser will not allow the images to be used even if they have the correct headers.

Here's an example

const gl = document.createElement("canvas").getContext("webgl");
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);

loadImage('https://i.imgur.com/ZKMnXce.png', false);
loadImage('https://i.imgur.com/u6VI8xz.jpg', true);

function loadImage(url, crossOrigin) {
  const img = new Image();
  img.onload = () => { upload(img); };
  if (crossOrigin) {
    img.crossOrigin = '';
  }
  img.src = url;
}

function upload(img) {
  // trap for cors error
  try {
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
    log(img.src, "uploaded image");
  } catch (e) {
    log(img.src, e);
  }
}

function log(...args) {
  const elem = document.createElement("pre");
  elem.textContent = [...args].join(' ');
  document.body.appendChild(elem);
}

pre { margin: 0; }

And here you can see even those the first image returned the CORS headers it was not allowed to be used because crossOrigin was not set

The second image has the same headers but it works because we set the crossOrigin attribute

Note that you might be able to include a script like this before the game scripts to kind of hack in CORS support.

(function() {

function isSameOrigin(url) {
  return (new URL(url, window.location.href)).origin === window.location.origin;
}

function needsCORS(url) {
  // not sure all the URLs that should be checked for
  return !isSameOrigin(url) && !url.startsWith("blob:") && !url.startsWith("data:");
}

const srcSetFn = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, 'src').set; 

Object.defineProperty(HTMLImageElement.prototype, 'src', {
  enumerable: true,
  set: function(url) {
     if (needsCORS(url)) {
       // Set if not already set
       if (this.crossOrigin !== undefined) {
         this.crossOrigin = '';
       }
     } else {
       this.crossOrigin = undefined;
     }
     // Set the original attribute
     srcSetFn.call(this, url);
  },
});

}());

这篇关于Webgl Cross Origin Images无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆