パッケージアプリchrome拡張機能を作成して、ユーザーがjavascriptコード(javascriptコンソールなど)を記述して実行できるようにします。
eval()
関数を使用してJSコードを実行したいと思います。
従来のjavascripteval
関数は、chrome拡張機能から呼び出されたときにエラーをスローします:
キャッチされないエラー:このコンテキストでは文字列からのコード生成は許可されていません
chrome拡張機能でeval
を使用するには、 サンドボックス を使用する必要がありますが、マニフェストにサンドボックスを書き込むと、次のエラーが発生します。
この拡張機能をインストールしようとすると、警告が表示されました。「サンドボックス」は、指定されたパッケージタイプ(テーマ、アプリなど)では許可されていません。
[〜#〜]更新[〜#〜]
この問題 によると、サンドボックスはパッケージアプリではサポートされていないため、2つの質問があります。
eval()
の代わりに使用できる別のメソッドはありますか?
サンドボックスなしでeval
を使用することは可能ですか? (おそらくセキュリティ上の理由ではないと思いますか?)
更新:
少なくとも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
_を含むスクリプトポリシーを設定しても効果はありません。これは意図的なものです。
上記のように、この制限を緩和することができます。
新しいパッケージアプリ(マニフェストバージョン2)について話していると思いますよね?
サンドボックスは、絶対に新しいパッケージアプリで使用できます。先週アップロードしたばかりです サンプル これはまさにそれを行います:ウィンドウが非表示のサンドボックス化されたiframeにメッセージを送信し、iframeがハンドルバーテンプレートをコンパイルし(ここでは代わりにevalを使用できます)、コンパイルされたHTMLを結果を表示するホスティングページ。
この他のサンプル をチェックすることもできます。これはまさにあなたが望むことをします。
だから、あなたの質問に直接答えるために:
1)いいえ、CSPの制限のためです。 Chromeパッケージ化されたアプリで動的JavaScriptを評価する唯一の方法は、サンドボックス化されたiframeです。それがアプリのオプションでない場合は、サーバーでJavaScriptコンテンツを送信して評価し、ユーザーへの結果(これはChromeパッケージ化されたアプリ)のオフライン機能を壊しますが)
2)いいえ、サンドボックス化されたiframeでのみeval()を使用できます。
角度から:$ scope。$ eval()を使用できます。
私が始めていたAngular.js chrome appが同じエラーを出した後、私はこの答えに到達しました。作者はAngular.jsについて言及していませんが、他の誰かがこれに遭遇した場合は、追加する必要がありますあなたのウェブページへのディレクティブ例えば.
<html ng-app ng-csp>
...
これにより、angular CSPセーフモードになります https://docs.angularjs.org/api/ng/directive/ngCsp
あなたは試すことができます...
function evalMe(code){
var script = document.createElement('script');
script.innerText = code;
document.querySelector('head').appendChild(script);
}
これは、無効にされていない限り、同じ効果を生み出すはずですが、私の知る限り、これは問題ありません。もちろん、スクリプトがerrors
の場合、string
をeval
にラップしない限り、そのことは聞こえません。
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追加のコードなしでプラグインを機能させるために、拡張機能eval
のwindow
メソッドをコードのiframeEval
メソッドで上書きできます。