チュートリアル: Manifest V2 に移行する

Chrome 18 でマニフェスト バージョン 1 のサポートは終了しました。マニフェスト バージョン 1 のサポート スケジュールに従って、サポートは段階的に終了します。バージョン 1 からバージョン 2 への変更は、API の変更とセキュリティの変更という 2 つの大きなカテゴリに分類されます。

このドキュメントでは、Chrome 拡張機能をマニフェスト バージョン 1 からバージョン 2 に移行する際のチェックリストを示します。さらに、これらの変更の意味と変更が行われた理由について、より詳細な概要を説明します。

API 変更のチェックリスト

  • browser_actions プロパティと chrome.browserActions API のどちらを使用していますか?

  • browser_actions を単数形の browser_action プロパティに置き換えます。

  • chrome.browserActionschrome.browserAction に置き換えます。

  • icons プロパティを default_icon に置き換えます。

  • name プロパティを default_title に置き換えます。

  • popup プロパティを default_popup に置き換えます(文字列にする必要があります)。

  • page_actions プロパティと chrome.pageActions API のどちらを使用していますか?

  • page_actionspage_action に置き換えます。

  • chrome.pageActionschrome.pageAction に置き換えます。

  • icons プロパティを default_icon に置き換えます。

  • name プロパティを default_title に置き換えます。

  • popup プロパティを default_popup に置き換えます(文字列にする必要があります)。

  • chrome.self プロパティを使用していますか?

  • chrome.extension に置き換えます。

  • Port.tab プロパティを使用していますか?

  • Port.sender に置き換えます。

  • chrome.extension.getTabContentses() API または chrome.extension.getExtensionTabs() API を使用しているか。

  • chrome.extension.getViews( { "type" : "tab" } ) に置き換えます。

  • 拡張機能でバックグラウンド ページを使用していますか?

  • background_page プロパティを background プロパティに置き換えます。

  • ページのコードを含む scripts プロパティまたは page プロパティを追加します。

  • persistent プロパティを追加して false に設定し、バックグラウンド ページをイベントページに変換します。

セキュリティ変更のチェックリスト

  • HTML ページでインライン スクリプト ブロックを使用していますか。

  • <script> タグ内の JS コードを削除し、外部 JS ファイル内に配置してください。

  • インライン イベント ハンドラ(ongo など)を使っているか。

  • HTML コードから削除し、外部 JS ファイルに移動して、代わりに addEventListener() を使用してください。

  • 拡張機能のパッケージに含まれるリソース(画像やスクリプトなど)にアクセスする必要があるウェブページに、コンテンツ スクリプトを挿入していますか?

  • web_accessible_resources プロパティを定義して、リソースを一覧表示します(必要に応じて、それらのリソースに個別のコンテンツ セキュリティ ポリシーを設定する)。

  • 拡張機能に外部ウェブページが埋め込まれていますか?

  • sandbox プロパティを定義します。

  • コードまたはライブラリで、eval()、新しい Function()innerHTMLsetTimeout() を使用していませんか?あるいは、動的に評価される JS コードの文字列を渡していますか?

  • JSON コードをオブジェクトに解析する場合は、JSON.parse() を使用します。

  • CSP に適したライブラリ(AngularJS など)を使用します。

  • マニフェストにサンドボックス エントリを作成し、影響を受けるコードをサンドボックス内で実行します。postMessage() を使用して、サンドボックス化されたページと通信します。

  • jQuery や Google アナリティクスなどの外部コードを読み込んでいますか?

  • ライブラリをダウンロードして拡張機能にパッケージ化し、ローカル パッケージから読み込むことを検討してください。

  • マニフェストの「content_security_policy」部分で、リソースを提供する HTTPS ドメインを許可リストに登録します。

API の変更の概要

マニフェスト バージョン 2 では、ブラウザ アクション API とページ アクション API にいくつかの変更が加えられ、古い API のいくつかが新しい API に置き換えられます。

ブラウザ操作の変更

ブラウザ アクション API の名称が次のように変更されます。

  • browser_actions プロパティと chrome.browserActions プロパティが、単数形の browser_actionchrome.browserAction に置き換えられました。
  • 以前の browser_actions プロパティには、iconsnamepopup プロパティがありました。次のメソッドに置き換えられました。

  • default_icon: ブラウザ アクション バッジ アイコン

  • default_name: バッジにカーソルを合わせたときにツールチップに表示されるテキスト

  • ブラウザ アクションの UI を表す HTML ページの default_popup(現在は文字列で、オブジェクトは不可)

ページ操作の変更

ブラウザ アクションの変更と同様に、ページ アクション API も変更されました。

  • page_actions プロパティと chrome.pageActions プロパティが、単数形の page_actionchrome.pageAction に置き換えられました。
  • 以前の page_actions プロパティには、iconsnamepopup プロパティがありました。以下のメソッドに置き換えられました。

  • default_icon: ページ アクション バッジ アイコン

  • default_name: バッジにカーソルを合わせたときにツールチップに表示されるテキスト

  • ページ アクションの UI を表す HTML ページの default_popup(現在は文字列で、オブジェクトは不可)

削除および変更された API

いくつかの拡張機能 API が削除され、対応する新しい API に置き換えられました。

  • background_page プロパティは background に置き換えられました。
  • chrome.self プロパティが削除されました。chrome.extension を使用してください。
  • Port.tab プロパティを Port.sender に置き換えました。
  • chrome.extension.getTabContentses() API と chrome.extension.getExtensionTabs() API が chrome.extension.getViews( { "type" : "tab" } ) に置き換えられました。

セキュリティの変更の概要

マニフェスト バージョン 1 からバージョン 2 への移行に伴い、セキュリティに関連する多くの変更が行われています。こうした変更の多くは、Chrome にコンテンツ セキュリティ ポリシーが導入されたことによるものです。このポリシーの詳細を確認し、その影響を理解する必要があります。

インライン スクリプトとイベント ハンドラは許可されません

コンテンツ セキュリティ ポリシーを使用しているため、HTML コンテンツにインラインで <script> タグを使用することはできません。これらを外部 JS ファイルに移動する必要があります。また、インライン イベント ハンドラもサポートされていません。たとえば、拡張機能に次のコードがあるとします。

<html>
<head>
  <script>
    function myFunc() { ... }
  </script>
</head>
</html>

このコードがあると実行時にエラーが発生します。この問題を解決するには、<script> タグの内容を外部ファイルに移動し、src='path_to_file.js' 属性で参照します。

同様に、多くのウェブ デベロッパーがよく使用する便利な機能であるインライン イベント ハンドラも実行されません。たとえば、次のような一般的なインスタンスについて考えてみましょう。

<body onload="initialize()">
<button onclick="handleClick()" id="button1">

これらは Manifest V2 拡張機能では機能しません。インライン イベント ハンドラを削除して外部 JS ファイルに配置し、代わりに addEventListener() を使用してイベント ハンドラを登録します。たとえば、JS コードで以下を使用します。

window.addEventListener("load", initialize);
...
document.getElementById("button1").addEventListener("click",handleClick);

これは、拡張機能の動作とユーザー インターフェース マークアップを分離する、はるかにわかりやすい方法です。

コンテンツを埋め込む

場合によっては、外部で使用できるコンテンツや外部ソースから取得できるコンテンツが拡張機能に埋め込まれている場合があります。

ウェブページ内の拡張機能コンテンツ: ウェブページに挿入されるコンテンツ スクリプトで使用されるリソース(画像、スクリプト、CSS スタイルなど)が拡張機能に埋め込まれている場合は、web_accessible_resources プロパティを使用してそれらのリソースを許可リストに登録し、外部のウェブページで使用できるようにする必要があります。

{
...
  "web_accessible_resources": [
    "images/image1.png",
    "script/myscript.js"
  ],
...
}

外部コンテンツの埋め込み: コンテンツ セキュリティ ポリシーでは、パッケージからローカル スクリプトとオブジェクトの読み込みのみが許可されます。これにより、外部の攻撃者が拡張機能に不明なコードを取り込むのを防ぐことができます。ただし、jQuery や Google アナリティクス コードなど、外部から提供されるリソースを読み込もうとしている場合もあります。変換には次の 2 つの方法があります。

  1. 関連するライブラリ(jQuery など)をローカルにダウンロードし、拡張機能にパッケージ化します。
  2. マニフェストの「content_security_policy」セクションで HTTPS オリジンを許可リストに登録することで、制限付きの CSP を緩和できます。Google アナリティクスのようなライブラリを組み込む場合のアプローチは次のとおりです。

    {
      ...,
      "content_security_policy": "script-src 'self'
      https://ssl.google-analytics.com; object-src 'self'",
      ...
    }
    

動的スクリプト評価の使用

おそらく、新しいマニフェスト v2 のスキームにおける最大の変更点の一つは、拡張機能が、eval() や新しい Function() などの動的なスクリプト評価手法を使用したり、setTimeout() などの eval() が使用される原因となる関数に JS コードの文字列を渡したりできなくなったことです。また、Google マップや特定のテンプレート ライブラリなど、よく使われる JavaScript ライブラリでも、こうした手法を使用することが確認されています。

Chrome には、ページを独自のオリジンで実行するためのサンドボックスが用意されています。この場合、Chrome へのアクセスは拒否されます。* API との統合なども可能です。新しいコンテンツ セキュリティ ポリシーで eval() などを使用するには:

  1. マニフェスト ファイルにサンドボックス エントリを作成します。
  2. サンドボックスのエントリに、サンドボックスで実行するページを指定します。
  3. postMessage() を介してメッセージを受け渡すことで、サンドボックス化されたページと通信します。

実施方法の詳細については、サンドボックス化の評価のドキュメントをご覧ください。

参考資料

マニフェスト バージョン 2 の変更は、デベロッパーがより安全で堅牢な拡張機能とアプリを構築できるようにすることを目的としています。マニフェスト バージョン 1 からバージョン 2 への変更の完全なリストについては、マニフェスト ファイルのドキュメントをご覧ください。サンドボックスを使用して安全でないコードを分離する方法については、サンドボックスの評価をご覧ください。コンテンツ セキュリティ ポリシーについて詳しくは、拡張機能関連のチュートリアルと HTML5Rocks の概要をご覧ください。