【问题标题】:Why am I getting the error "Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. "为什么我收到错误“未捕获的 SecurityError:无法在 'HTMLCanvasElement' 上执行 'toDataURL':可能无法导出受污染的画布。”
【发布时间】:2014-07-02 13:08:53
【问题描述】:

我已经查看了其他问题,但仍然无法找到答案。

当用户点击“保存项目”按钮时,该函数被触发:

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(/<\/?script\b.*?>/g, "");
  mattes_html = mattes_html.replace(/ on\w+=".*?"/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 + "&prodid=" + product_id + "&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 中使用的图像

【问题讨论】:

    标签: javascript


    【解决方案1】:

    您正在从本地文件系统加载文件,而不是使用 localhost 请求。

    通过 localhost 文件服务器运行您的应用程序,并确保仅通过 http:// 而不是从本地系统加载应用程序中的文件。 (即 c:/ 或 file:// 或 /usr)

    【讨论】:

    • 我没有使用本地主机。我正在使用一个实际的域。
    • 那么您遇到了跨域问题。出于安全原因,canvas 将禁止从其他域加载资产。
    • 我所有的图片都来自同一个域。我没有从其他域请求任何内容。
    • 我做了...我将这些东西添加到我的 .htaccess 文件中
    【解决方案2】:

    只需使用crossOrigin 属性

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

    【讨论】:

    • 它不起作用,因为在我的情况下,服务器没有发送 CORS 标头。如果没有crossOrigin 属性,我可以加载图像但使用它我不能
    • @IonelLupu 这与我目前遇到的问题相同,我可以将图像加载到画布,但我无法生成 toBaseURL()。你有没有找到任何解决方案?这真的很有帮助。
    • 不幸的是,我对此没有很好的解决方案。我的解决方案是拥有一个后端服务,它将下载图像并将其提供给前端。这样你就可以绕过错误。我知道这不好,但它有效。
    猜你喜欢
    • 2020-02-20
    • 1970-01-01
    • 2021-02-10
    • 2017-08-22
    • 2018-04-09
    • 1970-01-01
    • 2016-04-07
    • 2018-08-02
    • 2022-08-19
    相关资源
    最近更新 更多