Webgl Cross Origin Изображения не работают

1

У меня есть проблема с изображением кросс-оригинала, и я надеюсь, что вы сможете помочь.

Здесь 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

  • 0
    Вы проверили с помощью инструментов разработчика вашего браузера, действительно ли ваш сервер для domain1 возвращает правильные заголовки?
  • 0
    Привет @CBroe, видимо, заголовки, кажется, в порядке. HTTP / 1.1 200 OK Сервер: nginx / 1.6.2 Дата: вторник, 26 сентября 2017 09:33:11 GMT Тип контента: текст / html Длина контента: 4431 Дата последнего изменения: Вт , 26 сентября 2017 08:00:45 GMT Соединение: keep-alive ETag: "59ca092d-114f" Accept-Ranges: байты
Показать ещё 4 комментария
Теги:
nginx
webgl
cors

2 ответа

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 не был установлен

Изображение 174551

Второе изображение имеет одни и те же заголовки, но оно работает, потому что мы устанавливаем атрибут crossOrigin

Изображение 174551

Обратите внимание, что вы могли бы включить скрипт, подобный этому, до того, как скрипты игры станут видными в 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);
  },
});

}());
  • 0
    Спасибо, Гман, это работает!
-2

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню