Webgl 跨源图像不起作用
Webgl Cross Origin Images don't work
我遇到了一些关于跨域图片的问题,希望你能帮忙。
这是行为。
我有 2 个域,例如:
- domain1.com
- domain2.com
我在 domain1 上放了很多 html5 游戏。此域只是游戏存储库。
Domain2 是真正的网站(wordpress 网站),用户可以在其中玩托管在domain1 上的游戏。
为此,我对每场比赛都提出了 curl 请求。
在 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
但他们不是很有帮助。
我不想修改原始游戏文件。我正在寻找服务器端解决方案(如果存在)。如果没有,您有解决我的问题的想法吗?
我的配置有问题吗?我错过了什么吗?
感谢您的帮助。
瓦莱里奥
游戏必须请求跨源图像。仅仅返回正确的 headers 是不够的。如果游戏本身不通过设置 crossOrigin
属性请求跨源图像,那么浏览器将不允许使用图像,即使它们具有正确的 headers.
这是一个例子
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 headers 不允许使用,因为 crossOrigin
未设置
第二张图片具有相同的 headers 但它有效,因为我们设置了 crossOrigin
属性
请注意,您可能 能够在游戏脚本之前包含这样的脚本,以破解 CORS 支持。
(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);
},
});
}());
http://webgl-hooman.blogspot.ca/2018/01/cross-origin-image-cannot-be-loaded-in.html
CORS = 跨源资源共享。这是网页向图片服务器请求图片使用权限的一种方式。 cross origin是Google Chrome内置的安全保护,不允许用户访问本地文件(在这种情况下,您的 image/texture)。即使在 Safari 中,您也会收到 "the operation is insecure" 错误。你有几个选择。最简单的方法是让您的 webgl 应用程序从 Web 服务器(例如 IIS 或 Apache)运行。如果您使用 Windows,另一个选项是使用 Internet Explorer 或 Microsoft Edge 浏览器打开您的 webgl 应用程序。如果您是 运行 来自 Mac 使用 "FireFox" 浏览器的 webgl 应用程序,请将 crossorigin="anonymous" 添加到 HTML 中加载纹理的图像标签中。但是,如果您使用 "Windows" 操作系统或任何其他浏览器,即使在 Mac 中,这将不起作用!它只适用于 MAC+Firefox。因此,要么将您的图像标签更改为这个,要么简单地添加这个 var image = document.getElementById("texImage"); image.crossOrigin = "";更多信息,请阅读:https://webglfundamentals.org/webgl/lessons/webgl-cors-permission.html
我遇到了一些关于跨域图片的问题,希望你能帮忙。
这是行为。 我有 2 个域,例如: - domain1.com - domain2.com
我在 domain1 上放了很多 html5 游戏。此域只是游戏存储库。
Domain2 是真正的网站(wordpress 网站),用户可以在其中玩托管在domain1 上的游戏。 为此,我对每场比赛都提出了 curl 请求。
在 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
但他们不是很有帮助。
我不想修改原始游戏文件。我正在寻找服务器端解决方案(如果存在)。如果没有,您有解决我的问题的想法吗?
我的配置有问题吗?我错过了什么吗?
感谢您的帮助。
瓦莱里奥
游戏必须请求跨源图像。仅仅返回正确的 headers 是不够的。如果游戏本身不通过设置 crossOrigin
属性请求跨源图像,那么浏览器将不允许使用图像,即使它们具有正确的 headers.
这是一个例子
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 headers 不允许使用,因为 crossOrigin
未设置
第二张图片具有相同的 headers 但它有效,因为我们设置了 crossOrigin
属性
请注意,您可能 能够在游戏脚本之前包含这样的脚本,以破解 CORS 支持。
(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);
},
});
}());
http://webgl-hooman.blogspot.ca/2018/01/cross-origin-image-cannot-be-loaded-in.html
CORS = 跨源资源共享。这是网页向图片服务器请求图片使用权限的一种方式。 cross origin是Google Chrome内置的安全保护,不允许用户访问本地文件(在这种情况下,您的 image/texture)。即使在 Safari 中,您也会收到 "the operation is insecure" 错误。你有几个选择。最简单的方法是让您的 webgl 应用程序从 Web 服务器(例如 IIS 或 Apache)运行。如果您使用 Windows,另一个选项是使用 Internet Explorer 或 Microsoft Edge 浏览器打开您的 webgl 应用程序。如果您是 运行 来自 Mac 使用 "FireFox" 浏览器的 webgl 应用程序,请将 crossorigin="anonymous" 添加到 HTML 中加载纹理的图像标签中。但是,如果您使用 "Windows" 操作系统或任何其他浏览器,即使在 Mac 中,这将不起作用!它只适用于 MAC+Firefox。因此,要么将您的图像标签更改为这个,要么简单地添加这个 var image = document.getElementById("texImage"); image.crossOrigin = "";更多信息,请阅读:https://webglfundamentals.org/webgl/lessons/webgl-cors-permission.html