文字列として保存されたJavaScriptコードを実行する


173

文字列であるJavaScriptを実行するにはどうすればよいですか?

function ExecuteJavascriptString()
{
    var s = "alert('hello')";
    // how do I get a browser to alert('hello')?
}

回答:


227

11
気をつけて!これによりコードが実行されるため、この文字列をどこでどのように取得したかに注意してください。誰かが悪意のあるコードを文字列に挿入しようとする可能性があることに注意してください。
Jon

@divinciこれは「クロスサイトスクリプティング」と呼ばれています。こちらを参照してください:en.wikipedia.org/wiki/Cross-site_scripting
Brendon Shaw、

134

関数を使用して実行できます。例:

var theInstructions = "alert('Hello World'); var x = 100";

var F=new Function (theInstructions);

return(F());

3
しかし、結局のところ、それは呼び出しと同じではありませんvar F=function(){eval(theInstructions);};か?
ジョーンBerkefeld

14
はい、いいえ:evalコードも実行されますが、Function()の場合、コードはF()まで実行されません(ユースケース?構文エラーをチェックしますが、コードを実行したくない)
G3z

2
それのbeatifull ... @stefannew Function("alert('Hello World');")()
アンドレス・モラレス

私はこれをtry / catchブロック内で試しましたが、完全に機能します。これで、テキストブロックに入力されたJavaScriptコードを取得して関数に渡し、実行することができます。次に、catchブロックは、JavaScriptエンジンからのエラーメッセージをDOM要素に挿入し、コードにエラーを表示できます。誰かが私が書いた機能が必要な場合は、片付けたら、ここに投稿できます。
デビッドエドワーズ

@DavidEdwardsあなたがまだそれを持っているならそれを投稿して素晴らしいでしょう。
Anoop、

60

evalこの関数は、渡された文字列を評価します。

ただし、の使用はeval危険な場合があるため、注意して使用してください。

編集: annakataには良い点があります- eval 危険なだけでなく、 遅いです。これは、評価対象のコードをその場で解析する必要があるため、計算リソースが必要になるためです。


34
非常に危険で遅い-太字、斜体、下線、h1が必要
アナカタ09年

5
ページの他の場所にJavaScriptをロードするよりも遅く、解析する必要があることは疑わしいです。遅い場合は、別のスコープで行われているため、そのスコープのリソースの作成が強制される可能性があります。
cgp 2009年

6
eval()危険だと言えば。代替手段はありますか?
white_gecko

4
@coobird私はこれが少し遅れていることを知っていますが、なぜそれが危険なのですか?ユーザーは、コンソールを使用してWebサイトでJavaScriptコードを簡単に実行できます。
jkd 2015年

8
セキュリティがクライアント側のJavaScriptにまったく依存している場合、大きな時間を費やしてしまい、evalとは何の関係もありません。
マシュー

20

eval()を使用してください。

evalのW3学校ツアー。サイトにはevalの使用可能な例がいくつかあります。これについてはMozillaのドキュメントで詳しく説明されています。

おそらくます警告をたくさん得る安全にこれを使用してについてを。セキュリティ上の大きな問題であるため、ユーザーがeval()に何かを注入することを許可しないでください

また、eval()には別のスコープがあることも知りたいでしょう。


11
w3fools.com。W3Cはevalについて何も言うことがありません。あなたが何かの公式、ターゲットにリンクしたい場合ecma-international.org/ecma-262/5.1/#sec-15.1.2.1
Bergi

7
私は読みやすいものにリンクしたかった、何の公式へのリンク」にしたくなかった-何を見て、あなたがリンクされ、それがどのように使われるかの何の説明、ない例、いじくりする方法を与えない、そして単独で方法を説明します。初心者にとっては、これは完全に不適切なリンクです。ねえ、あなたはたまたま@bjorningeではないでしょう?
cgp

1
仕様はeval、W3Schoolsの記事よりも私によく説明しています。良い説明と例で読みやすいものは、developer.mozilla.org /en-US/docs/Web/JavaScript/Reference/… です。いいえ、私はビョルニンゲではありません
ベルギ

ドキュメントではないことに同意します。また、mozillaのページの方が全体像がよくなっていることに同意します。フィードバックに基づいて私の回答を少し調整しました
cgp '15

1
そのecma-international.orgリンクに関しては、JSの経験が15分を超えるすべての人が読みやすく、理解しやすいと説明します。それは非常にうれしいです。
i336_ 2017年

16

これを試して:

  var script = "<script type='text/javascript'> content </script>";
  //using jquery next
  $('body').append(script);//incorporates and executes inmediatelly

個人的にはテストしていませんが、動作するようです。


1
スクリプトでエスケープを閉じるのを忘れた> var script = "<script type = \" text / javascript \ "> content </ script \>";
rlib 2015年

1
なぜあなたは終わりをエスケープする必要があるのですか?
ジョールズ2017

11

より詳しくは、@ Hossein Hajizadeh aleradyが言ったことに少し似ていますが、

に代わるものがありeval()ます。

この関数setTimeout()は、ミリ秒間隔で何かを実行するように設計されており、実行されるコードはたまたま文字列としてフォーマットされます。

これは次のように機能します。

ExecuteJavascriptString(); //Just for running it

function ExecuteJavascriptString()
{
    var s = "alert('hello')";
    setTimeout(s, 1);
}

1 文字列を実行する前に1ミリ秒待機することを意味します。

それを行うには最も適切な方法ではないかもしれませんが、機能します。


0(ゼロ)を渡すことができるのに、なぜ1ミリ秒を無駄にするのsetTimeoutですか?いずれの場合も、実行が非同期になることに注意してください。つまり、setTimeout呼び出しに続くすべてのコードは、コードが渡されるに呼び出されますsetTimeout(0(ゼロ)で呼び出された場合でも)。
jox

Timeout️ちょうどsetTimeoutがどのように機能するかを説明したほうがいいと思った
アントンジュール

8
new Function('alert("Hello")')();

これが一番いい方法だと思います。


7

以下のようにevalを使用します。Evalは注意して使用する必要があります。「eval is evil」に関する単純な検索では、いくつかのポインターがスローされます。

function ExecuteJavascriptString()
{
    var s = "alert('hello')";
    eval(s);
}

2
ことで良いヒントについての簡単な検索「evalが悪である」 ありがとう!
Taptronic 2009年

5

多くの複雑で難読化されたスクリプトでこれを確認しました:

var js = "alert('Hello, World!');" // put your JS code here
var oScript = document.createElement("script");
var oScriptText = document.createTextNode(js);
oScript.appendChild(oScriptText);
document.body.appendChild(oScript);

5

特定の時間後に特定のコマンド(つまり文字列)を実行する場合-cmd = your code-InterVal = delay to run

 function ExecStr(cmd, InterVal) {
    try {
        setTimeout(function () {
            var F = new Function(cmd);
            return (F());
        }, InterVal);
    } catch (e) { }
}
//sample
ExecStr("alert(20)",500);

@SteelBrainは、ExecStr( "alert(20)"、500);によって実行されたサンプルを追加します。
Hossein Hajizadeh 2017年

1
なぜさValInterVal大文字?
Redwolfプログラム

4

nodeを使用していて、eval()nodejsが提供するコンテキストの影響に関心があるユーザー向けvm。別のコンテキストでコードの実行をサンドボックス化できるV8仮想マシンを作成します。

さらに一歩物事を取ることでvm2硬化されvmたVMは、信頼できないコードを実行することができます。

const vm = require('vm');

const x = 1;

const sandbox = { x: 2 };
vm.createContext(sandbox); // Contextify the sandbox.

const code = 'x += 40; var y = 17;';
// `x` and `y` are global variables in the sandboxed environment.
// Initially, x has the value 2 because that is the value of sandbox.x.
vm.runInContext(code, sandbox);

console.log(sandbox.x); // 42
console.log(sandbox.y); // 17

console.log(x); // 1; y is not defined.

2
これは「評価は悪だ」と言ってコンテキストや解決策を提供するのではなく、実際に問題を解決しようとします。+1 for you
Redwolfプログラム

3
eval(s);

しかし、ユーザーからデータを取得している場合、これは危険である可能性がありますが、ユーザーが自分のブラウザをクラッシュさせたことが問題であると思います。


1
丁度。Evalはサーバー側では危険です。クライアントでは...それほどではありません。ユーザーはブラウザのアドレスにjavascript:someevilcodeを入力するだけで、ブームになります。すぐそこに評価があります。
Esben Skov Pedersen

@EsbenSkovPedersen少なくともchromeでは防止されており、ユーザーevalからのコードを使用するサイトとは対照的に、ユーザーのアクションが必要です。たとえば、ページをロードするだけでユーザーが知らないうちに他のユーザーのアカウントを盗む可能性があります。
1j01

1
@ 1j01公平に言うと、私のコメントは5歳です。
Esben Skov Pedersen、2015

@EsbenSkovPedersenその通りです:)
1j01

2

これが浮気かどうかわからない:

window.say = function(a) { alert(a); };

var a = "say('hello')";

var p = /^([^(]*)\('([^']*)'\).*$/;                 // ["say('hello')","say","hello"]

var fn = window[p.exec(a)[1]];                      // get function reference by name

if( typeof(fn) === "function") 
    fn.apply(null, [p.exec(a)[2]]);                 // call it with params


2

私は同様の質問に答えていて、これを使用せずにこれを達成する方法についてさらに別のアイデアを得ましたeval()

const source = "alert('test')";
const el = document.createElement("script");
el.src = URL.createObjectURL(new Blob([source], { type: 'text/javascript' }));
document.head.appendChild(el);

上記のコードでは、オブジェクトURL(ブラウザーのメモリ内のファイルまたはBlobオブジェクトの表現)を作成するために、基本的にスクリプトを含むBlobを作成します。タグにsrcプロパティがあるため<script>、スクリプトは他のURLからロードされた場合と同じように実行されます。


2
function executeScript(source) {
    var script = document.createElement("script");
    script.onload = script.onerror = function(){ this.remove(); };
    script.src = "data:text/plain;base64," + btoa(source);
    document.body.appendChild(script);
}

executeScript("alert('Hello, World!');");


0
eval(s);

ただし、このevalは非常に強力であり、非常に危険です。実行しているスクリプトが安全であり、ユーザーが変更できないことをよりよく確信することができます。


1
JSでは、ユーザーは「javascript:document.write( "Hello World");」と入力するだけですべてを変更できます。ほとんどすべてのブラウザのアドレスバーに。
UnkwnTech

1
はい。ただし、グローバル変数を使用しない、クロージャー内で関数を非表示にするなどして、彼のために困難にすることができます。また、ペストのようなevalを回避することで=)
PatrikAkerstrand

0

mathjsを使用できます

上記のリンクからの抜粋:

// evaluate expressions
math.evaluate('sqrt(3^2 + 4^2)')        // 5
math.evaluate('sqrt(-4)')               // 2i
math.evaluate('2 inch to cm')           // 5.08 cm
math.evaluate('cos(45 deg)')            // 0.7071067811865476

// provide a scope
let scope = {
    a: 3,
    b: 4
}
math.evaluate('a * b', scope)           // 12
math.evaluate('c = 2.3 + 4.5', scope)   // 6.8
scope.c                                

scope任意のオブジェクトです。したがって、グローバルスコープをevalute関数に渡すと、alert()を動的に実行できる場合があります。

また、mathjsはサンドボックスで実行されるため、eval()よりもはるかに優れたオプションです。

ユーザーが式パーサーを介して悪意のあるJavaScriptコードを挿入しようとする可能性があります。mathjsの式パーサーは、これを不可能にするはずの式を実行するためのサンドボックス環境を提供します。未知のセキュリティ脆弱性が存在する可能性があるため、特にサーバー側で任意の式の実行を許可する場合は注意することが重要です。

新しいバージョンのmathjsはeval()またはFunction()を使用しません。

パーサーは、セキュリティ攻撃の主な原因であるJavaScriptの内部評価と新しい関数へのアクセスを積極的に防止します。Mathjsバージョン4以降は、内部ではJavaScriptのevalを使用しません。バージョン3以前では、コンパイルステップにevalを使用していました。これは直接セキュリティの問題ではありませんが、攻撃対象領域が拡大する可能性があります。


0

evalと新しい関数の作成の両方を使用してjavascriptを実行すると、多くのセキュリティリスクが伴います。

const script = document.createElement("script");
const stringJquery = '$("#button").on("click", function() {console.log("hit")})';
script.text = stringJquery;
document.body.appendChild(script);

文字列として受け取ったJavascriptを実行するには、このメソッドを使用します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.