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

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

ただいまの
回答率

91.36%

  • JavaScript

    11208questions

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

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

解決済

回答 1

投稿 2017/11/25 18:37 ・編集 2017/11/26 15:40

  • 評価
  • クリップ 0
  • VIEW 334

merico

score 2

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

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

コード

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


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

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

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

追記

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

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


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

まず, 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のレンダリング性能を鑑みるとある程度妥協が必要です)

"use strict";
//キャプチャのトリガ
out.onclick = e => {
    //目的の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 = "target.htm";
};

投稿 2017/11/25 20:31

編集 2017/11/26 11:20

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/25 20:38

    そうなのですか。
    知識不足でした。
    では、別の対策を取ってみます!

    お返事ありがとうございます!

    キャンセル

  • 2017/11/26 15: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)

    です。どのように対処したらよいでしょうか?

    キャンセル

  • 2017/11/26 15:13

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

    キャンセル

  • 2017/11/26 15:16

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

    キャンセル

  • 2017/11/26 15:23

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

    キャンセル

  • 2017/11/26 15:26

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

    キャンセル

  • 2017/11/26 15:32

    横から失礼します。

    To: mericoさん
    本スレッドで継続質問する場合は本質問を再オープンして、マルチスレッド先を閉じて下さい。
    teratailではマルチポストは非推奨とされています。
    https://teratail.com/questions/102065
    https://teratail.com/help#posted-otherservice

    キャンセル

  • 2017/11/26 15:37

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

    キャンセル

  • 2017/11/26 15:38

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

    キャンセル

  • 2017/11/26 15:54

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

    キャンセル

  • 2017/11/26 16:07

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

    キャンセル

  • 2017/11/26 16:09

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

    キャンセル

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

ただいまの回答率

91.36%

関連した質問

同じタグがついた質問を見る

  • JavaScript

    11208questions

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