为什么我会遇到脚本执行被阻止的错误?

8
我将使用http://cburgmer.github.io/rasterizeHTML.js/将HTML转换为画布。当我更改代码为:
var canvas = document.getElementById("save_image_canvas");
// rasterizeHTML.drawHTML('<div style="font-size: 20px;">Some <span style="color: green">HTML</span> with an image</div>', canvas);
rasterizeHTML.drawHTML(document.getElementById("mattes").innerHTML, canvas);

我在控制台中看到了以下错误:

由于文档的框架被沙盒化并且未设置“allow-scripts”权限,因此阻止在'Mysite/Custom_App/'中执行脚本。

所有脚本和内容都位于同一服务器上。

以下是完整函数:

function common_screenshot()
{
  var canvas = document.getElementById("save_image_canvas");
  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 = -1 * parseInt(document.getElementById("moulding_canvas").style.top);
  var moulding_left = -1 * parseInt(document.getElementById("moulding_canvas").style.left);

  console.log("top: " + moulding_top);
  rasterizeHTML.drawHTML(document.getElementById("mattes").innerHTML).then(function (renderResult) 
  {
    context.drawImage(renderResult.image, moulding_left, moulding_top);
  });
  var ctx = canvas.getContext('2d');
  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;
}

使用rasterizeHTML生成的图像在屏幕上显示正常,但是当我调用canvas.toDataURL时,生成的图像全部变成了黑色。


1
您所说的“同一服务器”,是指使用相同的端口而非file://吗?重要的是来源,而不是服务器. - Denys Séguret
我不确定你的意思是什么。 - AllisonC
请阅读我给出的链接:“服务器”在这里太模糊了,无法确定您是否做得正确。 - Denys Séguret
我认为我正在正确地做事。但我不确定。有注释的那一行可以正常运行,没有错误。 - AllisonC
也会影响CSScritic。因此我添加了该标签。 - Hugolpz
只是提醒其他人注意 - Adblock Chrome 扩展程序也可能导致此错误。 - danwild
2个回答

15
根据错误信息,您正在使用基于Webkit的浏览器,很可能是Chrome。当带有sandbox attribute<iframe>元素尝试运行JavaScript(仅在该属性中指定了allow-scripts时允许)时,会显示此错误消息(在这里引入)。查看rasterizeHTML源代码可知createHiddenSandboxedIFrame()函数创建此类框架,用于calculateDocumentContentSize(),将文档内容复制到临时沙盒框架中以测量其大小。显然,该文档还包含一些<script>标记,这些标记导致错误(不是因为脚本来源,而是因为通常禁止脚本)。
现在你的代码当然不会调用 calculateDocumentContentSize()。它被函数 drawDocumentImage() 调用,该函数由函数 doDraw() 调用,后者又由函数 rasterizeHTML.drawDocument() 调用,最终问题实际上是:你传入的 HTML 代码包含了 <script> 标签。
鉴于执行你正在绘制的 HTML 代码中的脚本似乎并不是你的意图(没有 executeJS 选项),你应该能够简单地将 <script> 标签移动到其他位置,以便它们不在 mattes 元素内部。如果这是不可能的,你仍然可以在源代码上运行一些正则表达式来删除所有脚本标签,例如:
var code = document.getElementById("mattes").innerHTML;
code = code.replace(/<\/?script\b.*?>/g, "");
rasterizeHTML.drawHTML(code, canvas);

编辑: 内联事件处理程序,如ondrop属性也会触发该警告。您也可以将其删除:

code = code.replace(/ on\w+=".*?"/g, "");

请注意,这只会帮助你消除警告。我怀疑这个警告不是导致图像空白的原因 - 所以你可能需要再问一个问题。

当我输出 document.getElementById("mattes").innerHTML 时,我得到的是 <div id="opening_0" style="background-color: #bfbfbf; position: absolute; left: 45px; top: 45px; height: 202.5px; width: 157.5px; overflow: hidden; z-index: 6;" ondrop="drag_drop_drop(event, this)" ondragover="drag_drop_allow_drop(event)" onclick="photos_add_selected_fid(this);">&nbsp;</div><canvas id="matte_canvas" width="247" height="292" style="z-index: 3; position: relative; background-color: rgb(255, 255, 255);"></canvas>,我没有看到任何脚本标签。 - AllisonC
我也尝试使用那段代码,但仍然出现错误。 - AllisonC
@AllisonC:ondrop属性和类似的属性也包含JavaScript代码。 - Wladimir Palant
那我需要做什么呢?我不能在原始代码中删除它们。 - AllisonC
@AllisonC:就像我在编辑中所说的那样,你把两个问题混在了一起。你问的是关于错误的问题,我已经回答了。为什么你的图像没有正确生成是一个完全不同的问题,这里没有足够的信息来回答它。 - Wladimir Palant
显示剩余7条评论

3
@WladimirPalant提供了一个很好的描述。如果您在一个您无法控制的网站上遇到这个问题,您可以使用以下命令启动Chrome,Chrome将接受这些脚本。
Windows:
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --args --allow-scripts

Linux:

google-chrome --args --allow-scripts

@Ciberman 在尝试此操作之前,是否关闭了所有Chrome进程?否则Chrome需要从头开始启动,否则无法正常工作。 - Ogglas
1
是的。我在我的脚本标签中添加了“allow-scripts”属性来解决问题。 - Ciberman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接