質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

8735閲覧

URLからhtml2canvasでURL先のWEBページをキャプチャしたい

merico

総合スコア12

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2017/11/25 09:37

編集2017/11/26 06:40

###URLからhtml2canvasでURL先のWEBページをキャプチャしたい
html2canva初心者です。
指定したURLからhtml2canvasで指定URL先のWEBページをキャプチャしたいです。

###コード

js

1$(function() { 2 html2canvas(Element(キャプチャしたい要素), { onrendered: function(canvas) { 3 var imgData = canvas.toDataURL(); 4 $('表示したい要素')[0].src = imgData; 5 }}); 6});

私の理解では、上記コード中の"Element"でキャプチャする要素を指定しているような気がします。

試したこと、考えたこと
1.ElementにURLを指定 → できない
2.URLを要素に変換??? → できない

どのように、実装したらよいでしょうか?
ご教授お願いいたします。

###追記
作りたいもの:chrome extention → 検索結果のプレビューを表示したい 
イメージ:serchpreview

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

追記)後日条件付きながら解決策を思いついたため, 記事後半にサンプルを追記しました.


(基本的に)出来ません.

まず, html2canvasはWEBページキャプチャツールではありません. HTMLDOMのレンダラです. つまりスタイル情報等を元にcanvas要素上にHTMLを描いているのです.

また, スタイル情報を現在表示しているwindow.documentを頂点とするDOMツリーから取得するため, html2canvasに渡すelementはこのDOMツリーに配置されている必要があります.

従って, 現在表示していないURLのWEBページ, もしくはオリジンが異なるためにそもそもHTMLDOMにアクセス出来ないURLのWEBページをhtml2canvasを用いて画像化することは出来ません.

なお, 単にWEBページのスクリーンショットを撮るだけであれば, WEBブラウザの開発ツールに相応の機能があるため, そちらを使ったほうが良いでしょう.
また, ヘッドレスChromeを用いてコマンドラインから目的のURLのWEBページを画像化する方法もあります.


なお, 同一オリジンのWEBページであればiframe要素に当該ページを読み込んだ後, html2canvasを後付で実行することで間接的に"キャプチャ"画像を取得することは可能です.
(が, html2canvasのレンダリング性能を鑑みるとある程度妥協が必要です)

JavaScript

1"use strict"; 2//キャプチャのトリガ 3out.onclick = e => { 4 //目的のURLをiframeに読み込む 5 const iframe = document.createElement("iframe"); 6 document.body.appendChild(iframe); 7 iframe.onload = e => { 8 const iwin = iframe.contentWindow; 9 //メインウインドウにキャプチャ結果を渡すコールバックの定義 10 iwin.__callback = function(id){ 11 iframe.remove(); 12 const canvas = document.createElement("canvas"); 13 canvas.width = id.width; 14 canvas.height = id.height; 15 canvas.getContext("2d").putImageData(id, 0, 0); 16 document.body.appendChild(canvas); 17 }; 18 //iframe内にhtml2canvasによるキャプチャ機構を挿入する 19 const doc = iwin.document; 20 const script = doc.createElement("script"); 21 script.textContent = ` 22 "use strict"; 23 { 24 const script = document.createElement("script"); 25 script.src = "html2canvas.min.js"; 26 script.onload = e => { 27 html2canvas(document.body, { 28 onrendered: canvas => window.__callback(canvas.getContext("2d").getImageData(0,0,canvas.width,canvas.height)), 29 width: 200, 30 height: 300 31 }); 32 } 33 document.head.appendChild(script); 34 }`; 35 doc.head.appendChild(script); 36 }; 37 iframe.src = "target.htm"; 38};

投稿2017/11/25 11:31

編集2017/11/26 02:20
defghi1977

総合スコア4756

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

merico

2017/11/25 11:38

そうなのですか。 知識不足でした。 では、別の対策を取ってみます! お返事ありがとうございます!
merico

2017/11/26 06:08 編集

詳しくありがとうございます! 教えていただいたコードを使用させていただきました。 ```javascript $(document).ready(function(){ "use strict"; //目的のURLをiframeに読み込む const iframe = document.createElement("iframe"); document.body.appendChild(iframe); iframe.onload = e => { const iwin = iframe.contentWindow; //メインウインドウにキャプチャ結果を渡すコールバックの定義 iwin.__callback = function (id) { iframe.remove(); const canvas = document.createElement("canvas"); canvas.width = id.width; canvas.height = id.height; canvas.getContext("2d").putImageData(id, 0, 0); document.body.appendChild(canvas); }; //iframe内にhtml2canvasによるキャプチャ機構を挿入する const doc = iwin.document; const script = doc.createElement("script"); script.textContent = ` "use strict"; { const script = document.createElement("script"); script.src = "html2canvas.min.js"; script.onload = e => { html2canvas(document.body, { onrendered: canvas => window.__callback(canvas.getContext("2d").getImageData(0,0,canvas.width,canvas.height)), width: 200, height: 300 }); } document.head.appendChild(script); }`; doc.head.appendChild(script); }; iframe.src = "www.google.co.jp";//googleにしてみました }) ``` としてみました。 実行結果で、エラーが出てしまいました。 エラー:Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame.at HTMLIFrameElement.iframe.onload.e(エラー箇所) エラー箇所:iwin.__callback = function (id) です。どのように対処したらよいでしょうか?
defghi1977

2017/11/26 06:13

このサンプルコードは同一オリジン、つまり「同じサイト」からでないと上手く行きません. セキュリティの観点から, あなた自作サイトから異なるオリジンの「http://www.google.co.jp」へのアクセスはできません. だから”基本的に無理”なんです.
merico

2017/11/26 06:16

理解しました… そういうことだったのですね。 素早い対応ありがとうございます!
defghi1977

2017/11/26 06:23

但し, これは無垢のWEBブラウザの話であって, WebExtensionとかuser scriptを使ってAPIに穴を開けることは出来ます. そのため, 利用環境やOS, ブラウザに条件を漬けることで実現可能性はもう少し広がります. また, サーバーサイドでWEBページをキャプチャしそれをクライアントに送信する方法もあります.
merico

2017/11/26 06:26

Chrome extensionを制作していて、検索結果webページのプレビューを表示したいと考えています。その場合の解決策等がありましたら教えていただいたきたいです。 イメージしているのは、searchpreviewというchrome extensionです。
merico

2017/11/26 06:37

ご指摘ありがとうございます。 先ほど、マルチスレッド先の削除リクエストをいたしました。
defghi1977

2017/11/26 06:38

searchpreviewはサーバーサイドでサムネイルを作っています. ですからhtml2canvasによる方法とは質が違います.
merico

2017/11/26 06:54

分かりました。 html2canvas以外の方法を考えます。 では、他にどのような方法があるのでしょうか? ご意見いただきたいです。
defghi1977

2017/11/26 07:07

当初の質問とは内容がかけ離れていますから, 本スレッドはここで終了とすべきでしょう. >他にどのような方法があるのでしょうか? 既に回答済みです. また, あなたの欲しい機能を実現しているアドオンが存在するのですから, いろいろ調査のしようはあるというものです. その上で判らないことがあったらもう一度質問して下さい.
merico

2017/11/26 07:09

長らくありがとうございました。 頑張ります!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問