У меня есть проблема с изображением кросс-оригинала, и я надеюсь, что вы сможете помочь.
Здесь beahviour. У меня есть 2 домена, например: - domain1.com - domain2.com
На domain1 я помещал много игр html5. Этот домен является только хранилищем игр.
Domain2 - это настоящий веб-сайт (сайт Wordpress), где пользователи могут играть в игры, размещенные на домене1. Для этого я сделал запрос на завиток для каждой игры.
В конфигурационном файле domain1 nginx я помещаю эти строки кода для включения совместного использования ресурсов Cross Origin:
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. Рисование изображений на холст с помощью img.crossOrigin = "Анонимный" не работает
но они не очень полезны.
Я бы не хотел изменять исходные файлы игры. Я ищу решение на стороне сервера, если оно существует. Если нет, есть ли у вас идея решить мою проблему?
Есть ли какая-то ошибка в моей конфигурации? Я что-то пропустил?
Спасибо вам за помощь.
Valerio
Игры должны запрашивать изображения с крестовым началом. Простого возврата правильных заголовков недостаточно. Если сами игры не запрашивают изображения перекрестного происхождения, задав атрибут 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
не был установлен
Второе изображение имеет одни и те же заголовки, но оно работает, потому что мы устанавливаем атрибут crossOrigin
Обратите внимание, что вы могли бы включить скрипт, подобный этому, до того, как скрипты игры станут видными в 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);
},
});
}());
http://webgl-hooman.blogspot.ca/2018/01/cross-origin-image-cannot-be-loaded-in.html
CORS = Перекрестный поиск ресурсов. Это способ веб-страницы запросить у сервера изображений разрешение на использование изображения. Крест-происхождение - это защита безопасности, которая встроена в Google Chrome, не позволяющая пользователям иметь доступ к локальным файлам (в данном случае ваш образ/текстура), Даже в Safari вы получите ошибку "операция небезопасна". У вас есть несколько вариантов. Самый простой способ - запустить приложение webgl с веб-сервера, такого как IIS или Apache. Другой вариант - открыть ваши приложения webgl, используя браузер Internet Explorer или Microsoft Edge, если вы используете Windows. Если вы используете приложение webgl с Mac с помощью браузера "FireFox", добавьте crossorigin = "anonymous" в свой тег изображения в HTML, где ваша текстура загружается. Но это не сработает, если вы используете операционную систему Windows или любые другие браузеры даже в Mac! Он работает только с MAC + Firefox. Так что либо смените свой тег изображения на это, либо просто добавьте это var image = document.getElementById("texImage"); image.crossOrigin = ""; Подробнее об этом читайте: https://webglfundamentals.org/webgl/lessons/webgl-cors-permission.html