web-dev-qa-db-ja.com

eval in chromeパッケージアプリ

パッケージアプリchrome拡張機能を作成して、ユーザーがjavascriptコード(javascriptコンソールなど)を記述して実行できるようにします。

eval()関数を使用してJSコードを実行したいと思います。

従来のjavascripteval関数は、chrome拡張機能から呼び出されたときにエラーをスローします:

キャッチされないエラー:このコンテキストでは文字列からのコード生成は許可されていません

chrome拡張機能でevalを使用するには、 サンドボックス を使用する必要がありますが、マニフェストにサンドボックスを書き込むと、次のエラーが発生します。

この拡張機能をインストールしようとすると、警告が表示されました。「サンドボックス」は、指定されたパッケージタイプ(テーマ、アプリなど)では許可されていません。

[〜#〜]更新[〜#〜]

この問題 によると、サンドボックスはパッケージアプリではサポートされていないため、2つの質問があります。

  1. eval()の代わりに使用できる別のメソッドはありますか?

  2. サンドボックスなしでevalを使用することは可能ですか? (おそらくセキュリティ上の理由ではないと思いますか?)

26
Charles

更新:

少なくとも2013年1月以降、Chromeは _unsafe-eval_ コンテンツセキュリティポリシー(CSP)ディレクティブを許可するようになりました。これにより、サンドボックスの外部でevalを実行できます。

eval()およびsetTimeout(String)setInterval(String)new Function(String)などのその親戚に対するポリシーは、_'unsafe-eval'_ポリシーに

次のような適切な [〜#〜] csp [〜#〜] を拡張マニフェストに追加します。

_"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
_

参照するバグfixedとマークされ、Chrome 22以降に含まれています。

_'unsafe-eval'_が導入される前は、_manifest_version: 2_拡張機能のCSPで任意のテキストをコードとして実行できるようにする方法はありませんでした。 当時 、Googleはこの制限を取り除く方法がないことを明らかにしました(サンドボックス以外):

インラインJavaScript、およびevalのような危険な文字列からJavaScriptへのメソッドは実行されません...インラインJavaScriptの実行に対する制限を緩和するメカニズムはありません。特に、_unsafe-inline_を含むスクリプトポリシーを設定しても効果はありません。これは意図的なものです。

上記のように、この制限を緩和することができます。

30
apsillers

新しいパッケージアプリ(マニフェストバージョン2)について話していると思いますよね?

サンドボックスは、絶対に新しいパッケージアプリで使用できます。先週アップロードしたばかりです サンプル これはまさにそれを行います:ウィンドウが非表示のサンドボックス化されたiframeにメッセージを送信し、iframeがハンドルバーテンプレートをコンパイルし(ここでは代わりにevalを使用できます)、コンパイルされたHTMLを結果を表示するホスティングページ。

この他のサンプル をチェックすることもできます。これはまさにあなたが望むことをします。

だから、あなたの質問に直接答えるために:

1)いいえ、CSPの制限のためです。 Chromeパッケージ化されたアプリで動的JavaScriptを評価する唯一の方法は、サンドボックス化されたiframeです。それがアプリのオプションでない場合は、サーバーでJavaScriptコンテンツを送信して評価し、ユーザーへの結果(これはChromeパッケージ化されたアプリ)のオフライン機能を壊しますが)

2)いいえ、サンドボックス化されたiframeでのみeval()を使用できます。

6
mangini

角度から:$ scope。$ eval()を使用できます。

1
Gabriel Bazán

私が始めていたAngular.js chrome appが同じエラーを出した後、私はこの答えに到達しました。作者はAngular.jsについて言及していませんが、他の誰かがこれに遭遇した場合は、追加する必要がありますあなたのウェブページへのディレクティブ例えば.

<html ng-app ng-csp>
...

これにより、angular CSPセーフモードになります https://docs.angularjs.org/api/ng/directive/ngCsp

1
rob

あなたは試すことができます...

function evalMe(code){
    var script = document.createElement('script');
    script.innerText = code;
    document.querySelector('head').appendChild(script);
}

これは、無効にされていない限り、同じ効果を生み出すはずですが、私の知る限り、これは問題ありません。もちろん、スクリプトがerrorsの場合、stringevalにラップしない限り、そのことは聞こえません。

function myHandler(err){
    // handle errors.   
}

function evalMe(code){
    var script = document.createElement('script');
    var wrapper = '(function(){ try{ @@ }catch(err){ myHandler(err); } })()';
    // Make sure the string has an ending semicolon
    code = code[code.length-1] === ';' ? code : code + ';';

    script.innerText = wrapper.replace('@@', code);
    document.querySelector('head').appendChild(script);
}

または、公式のメカニズムを使用することもできます

http://developer.chrome.com/beta/extensions/tabs.html#method-executeScript

ただし、これには バックグラウンドページ が必要であり、appページとバックグラウンドページの間に メッセージパッシング を使用する必要があります。

UPDATE:作業方法

Iframeと、拡張ページとbase64の間で受け渡されるメッセージを処理する<iframe>エンコードされたevalを使用して、dataURIのようなメソッドを作成できます。 githubのコード の作業コピーを取得できます。使用するには、リポジトリのクローンを作成するかダウンロードし、「クライアント」dirをパッケージ化されていない拡張機能としてchrome拡張機能マネージャーにインストールします。プラグインを駆動するコードは、app.jsにあります。

IframeEvalを使用してテストします。エラー通知は少しバグがありますが、evalは機能します。

@appsillers追加のコードなしでプラグインを機能させるために、拡張機能evalwindowメソッドをコードのiframeEvalメソッドで上書きできます。

1
AshHeskes