Почему я получаю ошибку «Uncaught SecurityError: не удалось выполнить ‘toDataURL’ на ‘HTMLCanvasElement’: испорченные холсты не могут быть экспортированы «.

#javascript

#javascript

Вопрос:

Я просмотрел другие вопросы, но все еще не могу найти ответ.

Когда пользователь нажимает кнопку «Сохранить проект», эта функция запускается:

 function common_save_project()
{
  var image = common_screenshot();
}
  

Это вызывает common_screenshot()

 function common_screenshot()
{
  var canvas = document.getElementById("save_image_canvas");
  var ctx = canvas.getContext('2d');
  if (typeof(moulding_canvas) === "undefined")
  {
    canvas.height = parseInt($("#matte_canvas").height());
    canvas.width = parseInt($("#matte_canvas").width());
  }
  else
  {
    canvas.height = parseInt($("#moulding_canvas").height());
    canvas.width = parseInt($("#moulding_canvas").width());
  }
  canvas.style.backgroundColor = "#FFFFFF";

  var moulding_top = 0;
  var moulding_left = 0;
  if (document.getElementById("moulding_canvas"))
  {
    moulding_top = -1 * parseInt(document.getElementById("moulding_canvas").style.top);
    moulding_left = -1 * parseInt(document.getElementById("moulding_canvas").style.left);
  }

  var mattes_html = document.getElementById("mattes").innerHTML;
  mattes_html = mattes_html.replace(/</?scriptb.*?>/g, "");
  mattes_html = mattes_html.replace(/ onw =".*?"/g, "");
  console.log(mattes_html);
  rasterizeHTML.drawHTML(mattes_html).then(function (renderResult) 
  {
    ctx.drawImage(renderResult.image, moulding_left, moulding_top);
  });

  ctx.drawImage(matte_canvas, moulding_left, moulding_top);
  if (typeof(moulding_canvas) !== "undefined")
  {
    ctx.drawImage(moulding_canvas, 0, 0);
  }
  //var image = new Image();
    //image.src = canvas.toDataURL("image/jpeg");
  //return image;
}
  

Затем создается новый холст, а рядом с ним находится кнопка проверки. При нажатии на это:

 function common_test()
{
  var canvas = document.getElementById("save_image_canvas");
  var image = new Image();
  image.setAttribute('crossOrigin','anonymous');
    image.src = canvas.toDataURL("image/jpeg");
  $.ajax
  (
    {
      type: "POST",
      processData: false,
      url:  SITE_URL   "/system/xml/import/"   app_type   "/"   session_id   "/?prjid="   project_id,
      data: "xml="   common_order_xml   "amp;prodid="   product_id   "amp;file="   image.src
    }
  ).done(function( msg ) 
  {
      console.log("Project saved. "   msg);
  });
}
  

Однако, когда я нажимаю эту кнопку, я получаю сообщение об ошибке:

 Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. 
  

РЕДАКТИРОВАТЬ: Похоже, что ошибка возникает, когда у меня есть следующее:

 rasterizeHTML.drawHTML(mattes_html).then(function (renderResult) 
{
  ctx.drawImage(renderResult.image, moulding_left, moulding_top);
});
  

Есть ли другое решение, которое я могу использовать, чтобы превратить html-разметку в изображение, которое я затем могу использовать в canvas.toURL

Ответ №1:

Вы загружаете файлы из локальной файловой системы, вместо того, чтобы использовать запрос localhost.

Запустите ваше приложение через файловый сервер localhost и убедитесь, что файлы в вашем приложении загружаются только через http: //, а не из локальной системы. (т. Е. c: / или file: // или /usr)

Комментарии:

1. Я не использую localhost. Я использую реальный домен.

2. Тогда у вас проблемы с междоменностью. по соображениям безопасности canvas запретит ресурсы, загруженные из другого домена.

3. Все мои изображения поступают из одного домена. Я ничего не запрашиваю из другого домена.

4. Прочитайте о испорченных холстах: developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image

5. Я сделал… Я добавил этот материал в свой файл .htaccess

Ответ №2:

Просто используйте crossOrigin атрибут

 var image= new Image();
image.setAttribute('crossOrigin', 'anonymous');
image.src = url;
  

Комментарии:

1. Это не работает, потому что в моем случае сервер не отправляет заголовки CORS. Без crossOrigin атрибута я могу загружать изображения, но использовать его я не могу

2. @IonelLupu это та же проблема, что и у меня в настоящее время, я могу загружать изображения на холст, но я не могу сгенерировать toBaseURL(). Вы нашли какое-либо решение для этого? Это было бы действительно полезно.

3. К сожалению, я не нашел хорошего решения для этого. Мое решение состоит в том, чтобы создать серверную службу, которая загрузит изображение и предоставит его интерфейсу. Таким образом, вы обойдете ошибку. Я знаю, что это нехорошо, но это работает.