javascript Codemirror & html2canvas:将 iFrame 保存为图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25979469/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 05:20:15  来源:igfitidea点击:

Codemirror & html2canvas: Save iFrame as Image

javascriptjqueryiframecodemirrorhtml2canvas

提问by Michael Schwartz

Fiddle 1 (Using html2canvas): http://liveweave.com/HM9hSY
Fiddle 2 (Using html2canvaswithout Codemirror): http://liveweave.com/rS8yxI
Fiddle 3 (Using html2canvaswith Codemirror): http://liveweave.com/TF3Ono
Fiddle 4 (Using html2canvaswith Codemirror): http://liveweave.com/hqPoQg

小提琴1(使用html2canvas):http://liveweave.com/HM9hSY
小提琴2(使用html2canvasCodemirror):http://liveweave.com/rS8yxI
小提琴3(使用html2canvasCodemirror):http://liveweave.com /TF3Ono
Fiddle 4(使用html2canvasCodemirror):http: //liveweave.com/hqPoQg

Today I wanted to try and export an iframe as an Image. I did some research on this and came across a plugin called html2canvaswhich can save html as an image. (The documentation can be viewed here).

今天我想尝试将 iframe 导出为图像。我对此做了一些研究,并发现了一个名为html2canvas的插件,它可以将 html 保存为图像。(可以在此处查看文档)。

Capture HTML Canvas as gif/jpg/png/pdf?
Using HTML5/Canvas/JavaScript to take in-browser screenshots

将 HTML Canvas 捕获为 gif/jpg/png/pdf?
使用 HTML5/Canvas/JavaScript 在浏览器中截取屏幕截图

The first fiddleis just an experiment so save html as an image. (This fiddle is not using Codemirror)
The second fiddlesaves the image but doesn't grab the iframe preview given from source. (This fiddle is not using Codemirror)
The third fiddledoes not save an image. (This fiddle is not using Codemirror)

一个小提琴只是一个实验,所以将 html 保存为图像。(此拨弄不在使用Codemirror
第二小提琴保存图像,但不抓住从源给定的IFRAME预览。(此拨弄不在使用Codemirror)
第三小提琴不保存的图像。(这个小提琴没有使用Codemirror

My problem is with the 2ndand 3rdfiddles where [html2canvas][17] does not save the iframe's preview.

我的问题是第二个第三个小提琴 [html2canvas][17] 不保存 iframe 的预览。

I've been playing with this throughout yesterday and today and I haven't been successful.

我昨天和今天一直在玩这个,但我没有成功。

Today I decided to try and use Codemirror's code editor to render what I want instead.

今天我决定尝试使用 Codemirror 的代码编辑器来渲染我想要的东西。

Basically I take a screenshot of the body and embed an image into it.

基本上,我截取身体的屏幕截图并将图像嵌入其中。

(This is Fiddle 4I'm referring to).

(这是我指的Fiddle 4)。

I then open the image in a new window using window.openafter that I reset the code editor back to where it was.

然后我在新窗口中打开图像,然后window.open我将代码编辑器重置回原来的位置。

Is it possible to save an iframe's preview/source as an image? Am I doing anything wrong to achieve this effect?

是否可以将 iframe 的预览/源保存为图像?为了达到这种效果,我做错了什么吗?

$(document).ready(function() {
  $("#saveimg").click(function() {
    html2canvas($("#preview"), {
      onrendered: function(canvas) {
        var myImage = canvas.toDataURL("image/png");
        $("#imgprev").html("<img src='"+ myImage +"' />");
      }
    });
  });
});
<script src="https://raw.github.com/niklasvh/html2canvas/gh-pages/build/html2canvas.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<link type='text/css' rel='stylesheet' href='http://necolas.github.io/normalize.css/3.0.1/normalize.css' />

<div align="center">
  <p>
    <button id="saveimg">
      Save as Image
    </button>
  </p>
</div>
<iframe id="preview" src="http://duckduckgo.com/"></iframe>
<div id="imgprev"></div>
<canvas id="mycanvas"></canvas>

采纳答案by Michael Schwartz

Fiddle: http://liveweave.com/LHfsld
Fiddle: http://jsbin.com/xutivucanaye/1/edit

小提琴:http
: //liveweave.com/LHfsld小提琴:http: //jsbin.com/xutivucanaye/1/edit

It's not the best solution and a bit grotesque but I got it to work. Well kind of.

这不是最好的解决方案,有点怪诞,但我让它起作用了。好样的。

It doesn't work well with embedded images, iFrames, and it'll neverhave full CSS support (You can read why from html2canvas's FAQ)

它不适用于嵌入图像、iFrame,并且永远不会有完整的 CSS 支持(您可以从html2canvas 的常见问题解答中了解原因)

Here's my entire snippet:

这是我的整个片段:

<!DOCTYPE html>
<html>
  <head>
    <title>Snap a Picture of Preview</title>
    <meta charset='utf-8'>
    <meta name='viewport' content='initial-scale=1.0'>
    <meta http-equiv='X-UA-Compatible' content='IE=9' />
    <link type='text/css' rel='stylesheet' href='http://necolas.github.io/normalize.css/3.0.1/normalize.css'/>
    <script type='text/javascript' src='http://code.jquery.com/jquery-latest.min.js'></script>
    <script src='https://raw.github.com/niklasvh/html2canvas/gh-pages/build/html2canvas.js'></script>
    <script src='http://codemirror.net/lib/codemirror.js'></script>
    <script src='http://codemirror.net/mode/xml/xml.js'></script>
    <script src='http://codemirror.net/mode/javascript/javascript.js'></script>
    <script src='http://codemirror.net/mode/css/css.js'></script>
    <script src='http://codemirror.net/mode/htmlmixed/htmlmixed.js'></script>
    <link rel='stylesheet' href='http://codemirror.net/lib/codemirror.css'>
    <link rel='stylesheet' href='http://codemirror.net/doc/docs.css'>
    <script src='http://codemirror.net/mode/htmlmixed/htmlmixed.js'></script>
    <script src='http://codemirror.net/addon/edit/closetag.js'></script>
    <script src='http://codemirror.net/addon/edit/matchbrackets.js'></script>
    <script src='http://codemirror.net/addon/selection/active-line.js'></script>
    <style type='text/css'>
      .CodeMirror {
        float: left;
        width: 50%;
        border: 1px solid black;
      }

      iframe {
        width: 49%;
        float: left;
        height: 300px;
        border: 1px solid black;
        border-left: 0;
      }

      #beforeiframesnap {
        position: absolute;
        top: -500000px;
        left: -500000px;
        width: 0;
        height: 0;
        opacity: 0;
        overflow: hidden;
      }
    </style>
  </head>
  <body>
    <div align='center'>
      <button class='snapFrame'>Snap</button>
    </div>
    <textarea id='code' name='code'><!DOCTYPE html>
<html>
  <head>
    <meta charset=utf-8>
    <title>HTML5 canvas demo</title>
    <style>p {font-family: monospace;}</style>
  </head>
  <body>
    <p>Canvas pane goes here:</p>
    <canvas id=pane width=300 height=200></canvas>

    <script>
      var canvas = document.getElementById('pane');
      var context = canvas.getContext('2d');

      context.fillStyle = 'rgb(250,0,0)';
      context.fillRect(10, 10, 55, 50);

      context.fillStyle = 'rgba(0, 0, 250, 0.5)';
      context.fillRect(30, 30, 55, 50);
    </script>
  </body>
</html></textarea>
    <textarea id='beforeiframesnap'></textarea>
    <iframe id='preview'></iframe>
    <div id='imgprev'></div>

    <script type='text/javascript'>
      $('#beforeiframesnap').val("");
      // Append JS library to HTML <head>
      function appendJSLib(txt) {
        var textArea = editor.getValue();
        var searchText = textArea.search('<head>');
        if(searchText>0) {
          txt = '<head>'+'\n'+txt;
          var updatedTextArea = textArea.replace('<head>',txt);
          editor.setValue(updatedTextArea);
        }
        else {
          reset();
          alert('WARNING! The &lt;head&gt tag seems to be missing in your HTML. Although your code may still work, we highly recommened that you have a valid HTML syntax. Please refer to the new document of correct formatted');
          txt = txt+textArea;
          htmlEditor.setLine(0, txt);
          return false;
        }
      }
      // Append script to HTML <body>
      function appendScript(txt) {
        var textArea = editor.getValue();
        var searchText = textArea.search('<body>');
        if(searchText>0) {
          txt = '<body>'+'\n'+txt;
          var updatedTextArea = textArea.replace('<body>',txt);
          editor.setValue(updatedTextArea);
        }
        else {
          reset();
          alert('WARNING! The <body> tag seems to be missing in your HTML. Although your code may still work, we highly recommened that you have a valid HTML syntax. Please refer to the new document of correct formatted');
          txt = txt+textArea;
          htmlEditor.setLine(0, txt);
          return false;
        }
      }

      $('.snapFrame').on('click', function() {
        $('#beforeiframesnap').val("").val(editor.getValue());
        txt = '<'+'script type=\'text/javascript\' src=\'http://code.jquery.com/jquery-latest.min.js\'>'+'</'+'script'+'>';
        appendJSLib(txt);
        txt = '<'+'script type=\'text/javascript\' src=\'https://raw.github.com/niklasvh/html2canvas/gh-pages/build/html2canvas.js\'>'+'</'+'script'+'>';
        appendJSLib(txt);
        txt = '<'+'script type=\'text/javascript\'>\n$(document).ready(function() {\n  html2canvas($(\'body\'), {\n    onrendered: function(canvas) {\n      var myImage = canvas.toDataURL(\'image/png\');\n      $(\'body\').html(\'<img src=\'+ myImage +\' />\');      window.open(\'javascript:document.write("<img src=\'+ myImage +\' />")\', \'Opened Page\', \'width=660, height=440\');\n    }\n  });\n});\n</'+'script'+'>';
        appendScript(txt);

        setTimeout(function() {
          editor.setValue($('#beforeiframesnap').val());
        }, 1200);
      });

      var delay;

      // Initialize CodeMirror editor
      var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
        mode: 'text/html',
        tabMode: 'indent',
        styleActiveLine: true,
        lineNumbers: true,
        lineWrapping: true,
        autoCloseTags: true
      });

      // Live preview
      editor.on('change', function() {
        clearTimeout(delay);
        delay = setTimeout(updatePreview, 300);
      });

      function updatePreview() {
        var previewFrame = document.getElementById('preview');
        var preview =  previewFrame.contentDocument ||  previewFrame.contentWindow.document;
        preview.open();
        preview.write(editor.getValue());
        preview.close();
      }
      setTimeout(updatePreview, 300);
    </script>
  </body>
</html>

回答by Marijn

I suspect you are running into cross-origin restrictions. If you were able to open http://mybank.comin an iframe and get a screenshot of the resulting page, that might leak private information that was only meant for the user (whose session will be used). Thus, browser will not let you do this.

我怀疑您遇到了跨域限制。如果您能够http://mybank.com在 iframe 中打开并获取结果页面的屏幕截图,则可能会泄露仅适用于用户(将使用其会话)的私人信息。因此,浏览器不会让你这样做。