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

这里的行为。
例如,我有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



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

但是它们并不是很有帮助。

我不想修改原始游戏文件。我正在寻找服务器端解决方案(如果存在)。如果没有,您是否有解决我问题的想法?

我的配置是否存在错误?我想念什么吗?

感谢您的帮助。

瓦列里奥

最佳答案

游戏必须请求跨源图像。仅返回正确的标头是不够的。如果游戏本身不通过设置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,该图片被禁止使用

javascript - Webgl Cross Origin Images无法正常工作-LMLPHP

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

javascript - Webgl Cross Origin Images无法正常工作-LMLPHP

请注意,您可能可以在游戏脚本之前包含类似这样的脚本,以便在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);
  },
});

}());

09-25 15:29