Webgl Cross Origin图像无法正常工作

时间:2017-09-26 09:14:03

标签: javascript html5 nginx cors webgl

我对跨源图像有一些问题,希望你能提供帮助。

这里是beahviour。 我有2个域名,例如: - domain1.com - domain2.com

在domain1上我放了许多html5游戏。该域名只是游戏的存储库。

Domain2是真正的网站(wordpress网站),用户可以在其中播放domain1上托管的游戏。 为此,我为每场比赛提出了一个卷曲请求。

在domain1 nginx配置文件中,我将这些代码行用于启用跨源资源共享:


    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;
    }

这解决了许多游戏的一些问题,但有些游戏仍然无效,我得到了这个js错误:


    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

我在网上做了一些研究,我发现了这些文章 https://webglfundamentals.org/webgl/lessons/webgl-cors-permission.html Drawing images to canvas with img.crossOrigin = "Anonymous" doesn't work

但他们不是很有帮助。

我不想修改原始游戏文件。如果它存在,我正在寻找服务器端解决方案。如果没有,你有什么想法解决我的问题吗?

我的配置中是否有错误?我错过了什么吗?

感谢您的帮助。

瓦莱里奥

2 个答案:

答案 0 :(得分:2)

游戏必须要求交叉原始图像。简单地返回正确的标题是不够的。如果游戏本身不通过设置crossOrigin属性请求交叉原始图像,则浏览器将不允许使用图像,即使它们具有正确的标题。

这是一个例子

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; }

在这里,您甚至可以看到第一张图片返回了CORS标题但由于crossOrigin未设置而未被允许使用

enter image description here

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

enter image description here

请注意,可能能够在游戏脚本之前包含这样的脚本,以便在CORS支持中进行攻击。

(function() {

function isSameOrigin(url) {
  return (new URL(url)).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);
  },
});

}());

答案 1 :(得分:-1)

http://webgl-hooman.blogspot.ca/2018/01/cross-origin-image-cannot-be-loaded-in.html

CORS =跨源资源共享。这是网页向图像服务器请求使用图像的权限的一种方式。交叉来源是Google Chrome中内置的安全保护,不允许用户访问本地文件(在这种情况下是您的图像) /质地)。即使在Safari中,你也会得到"操作不安全"错误。你有几个选择。最简单的方法是让您的webgl应用程序从IIS或Apache等Web服务器运行。另一个选项是,如果您使用的是Windows,则使用Internet Explorer或Microsoft Edge浏览器打开您的webgl应用程序。如果您使用" FireFox"从Mac运行您的webgl应用程序浏览器,添加crossorigin ="匿名"在HTML中加载纹理的图像标记。但是,如果你正在使用" Windows"操作系统或任何其他浏览器甚至在Mac中!它只适用于MAC + Firefox。因此要么将图像标记更改为此图标,要么添加此var image = document.getElementById(" texImage"); image.crossOrigin ="&#34 ;;有关详情,请阅读:https://webglfundamentals.org/webgl/lessons/webgl-cors-permission.html