ฉันจะรัน JavaScript บางตัวที่เป็นสตริงได้อย่างไร
function ExecuteJavascriptString()
{
var s = "alert('hello')";
// how do I get a browser to alert('hello')?
}
ฉันจะรัน JavaScript บางตัวที่เป็นสตริงได้อย่างไร
function ExecuteJavascriptString()
{
var s = "alert('hello')";
// how do I get a browser to alert('hello')?
}
คำตอบ:
ด้วยeval("my script here")
ฟังก์ชั่น
คุณสามารถรันมันด้วยฟังก์ชั่น ตัวอย่าง:
var theInstructions = "alert('Hello World'); var x = 100";
var F=new Function (theInstructions);
return(F());
var F=function(){eval(theInstructions);};
หรือเปล่า
new Function("alert('Hello World');")()
eval
ฟังก์ชั่นจะประเมินสตริงที่ส่งผ่านไปมัน
แต่การใช้งานeval
อาจเป็นอันตรายดังนั้นควรใช้ด้วยความระมัดระวัง
แก้ไข: annakata มีจุดดี - ไม่เพียง แต่เป็นeval
อันตรายก็เป็น ช้า นี่เป็นเพราะรหัสที่จะประเมินจะต้องมีการแยกวิเคราะห์ในจุดที่จะใช้ทรัพยากรการคำนวณบางอย่าง
eval()
อันตราย มีทางเลือกอื่นอีกไหม?
ใช้ eval ()
ทัวร์ W3 ของโรงเรียน evalEVAL ไซต์มีตัวอย่าง eval ที่ใช้งานได้ เอกสาร Mozilla ครอบคลุมรายละเอียดนี้
คุณอาจได้รับคำเตือนมากมายเกี่ยวกับการใช้สิ่งนี้อย่างปลอดภัย ไม่อนุญาตให้ผู้ใช้ฉีดสิ่งใดก็ตามลงใน eval ()เนื่องจากเป็นปัญหาด้านความปลอดภัยขนาดใหญ่
นอกจากนี้คุณยังจะต้องการที่จะรู้ว่า EVAL () มีความแตกต่างกันขอบเขต
eval
ให้ฉันดีกว่าบทความ W3Schools บางสิ่งบางอย่างที่อ่านได้มีคำอธิบายที่ดีและตัวอย่างจะdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/... และไม่ฉันไม่ใช่ bjorninge
ลองสิ่งนี้:
var script = "<script type='text/javascript'> content </script>";
//using jquery next
$('body').append(script);//incorporates and executes inmediatelly
โดยส่วนตัวฉันไม่ได้ทดสอบ แต่ดูเหมือนว่าจะทำงาน
บิตเหมือนกับสิ่งที่@Hossein Hajizadeh กล่าวถึงแม้ว่าในรายละเอียดเพิ่มเติม
มีทางเลือกeval()
คือ
ฟังก์ชั่น setTimeout()
ถูกออกแบบมาเพื่อรันบางสิ่งหลังจากช่วงเวลาหนึ่งมิลลิวินาทีและรหัสที่จะดำเนินการจึงเกิดขึ้นเพื่อจัดรูปแบบเป็นสตริง
มันจะทำงานเช่นนี้:
ExecuteJavascriptString(); //Just for running it
function ExecuteJavascriptString()
{
var s = "alert('hello')";
setTimeout(s, 1);
}
1
หมายความว่ามันจะรอ 1 มิลลิวินาทีก่อนที่จะดำเนินการสตริง
มันอาจไม่ใช่วิธีที่ถูกต้องที่สุด แต่ก็ใช้งานได้
setTimeout
? โปรดทราบว่าในกรณีใด ๆ มันจะทำให้การดำเนินการไม่ตรงกัน หมายความว่ารหัสทั้งหมดที่ตามหลังการsetTimeout
โทรจะถูกเรียกใช้ก่อนที่รหัสจะถูกส่งไปยังsetTimeout
(แม้ว่าจะถูกเรียกด้วย 0 (ศูนย์))
new Function('alert("Hello")')();
ฉันคิดว่านี่เป็นวิธีที่ดีที่สุด
ใช้evalดังนี้ ควรใช้ Eval ด้วยความระมัดระวังการค้นหาอย่างง่าย ๆ เกี่ยวกับ " eval is evil " ควรจะพอยน์เตอร์
function ExecuteJavascriptString()
{
var s = "alert('hello')";
eval(s);
}
ตรวจสอบเรื่องนี้กับสคริปต์ที่ซับซ้อนและยุ่งเหยิงมากมาย:
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);
หากคุณต้องการรันคำสั่งเฉพาะ (นั่นคือสตริง) หลังจากเวลาที่กำหนด - cmd = รหัสของคุณ - InterVal = หน่วงเวลาที่จะเรียกใช้
function ExecStr(cmd, InterVal) {
try {
setTimeout(function () {
var F = new Function(cmd);
return (F());
}, InterVal);
} catch (e) { }
}
//sample
ExecStr("alert(20)",500);
Val
ในInterVal
ตัวพิมพ์ใหญ่
สำหรับผู้ใช้ที่กำลังใช้โหนดและมีความกังวลกับผลกระทบบริบทของeval()
nodejs vm
ข้อเสนอ มันสร้างเครื่องเสมือน V8 ที่สามารถแซนด์บ็อกซ์ประมวลผลรหัสของคุณในบริบทที่แยกต่างหาก
การก้าวไปอีกขั้นหนึ่งเป็นเรื่องยากvm2
ที่จะvm
ยอมให้ vm รันโค้ดที่ไม่น่าเชื่อถือ
https://nodejs.org/api/vm.html - เป็นทางการ nodejs / vm
https://github.com/patriksimek/vm2 - ขยาย vm2
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.
eval(s);
แต่สิ่งนี้อาจเป็นอันตรายได้หากคุณกำลังรับข้อมูลจากผู้ใช้แม้ว่าฉันคิดว่าพวกเขาทำผิดพลาดเบราว์เซอร์ของตัวเองนั่นเป็นปัญหาของพวกเขา
eval
มีรหัสจากผู้ใช้ซึ่งอาจทำให้ผู้ใช้ขโมยบัญชีของผู้ใช้โดยที่พวกเขาไม่ทราบเพียงแค่โหลดหน้าเว็บ
ไม่แน่ใจว่านี่เป็นการโกงหรือไม่:
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
ฟังก์ชั่นใหม่และApply ()ทำงานร่วมกันด้วย
var a=new Function('alert(1);')
a.apply(null)
eval()
นี้จะดีกว่า developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
ฉันกำลังตอบคำถามที่คล้ายกันและยังมีความคิดอื่นวิธีการบรรลุนี้โดยไม่ต้องใช้eval()
:
const source = "alert('test')";
const el = document.createElement("script");
el.src = URL.createObjectURL(new Blob([source], { type: 'text/javascript' }));
document.head.appendChild(el);
ในโค้ดข้างต้นคุณจะสร้าง Blob ซึ่งมีสคริปต์ของคุณเพื่อสร้าง URL ของวัตถุ (การแสดงของไฟล์หรือวัตถุ Blob ในหน่วยความจำเบราว์เซอร์) เนื่องจากคุณมีsrc
คุณสมบัติบน<script>
แท็กสคริปต์จะถูกดำเนินการเช่นเดียวกับถ้ามันถูกโหลดจาก URL อื่น ๆ
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!');");
evalควรทำมัน
eval(s);
eval(s);
โปรดจำไว้ว่า eval นั้นมีประสิทธิภาพมากและค่อนข้างไม่ปลอดภัย คุณควรมั่นใจว่าสคริปต์ที่คุณเรียกใช้นั้นปลอดภัยและไม่มีผู้ใช้ที่ไม่น่าเชื่อถือ
หนึ่งสามารถใช้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
เป็นวัตถุใด ๆ ดังนั้นหากคุณส่งขอบเขตทั่วโลกไปยังฟังก์ชันประเมินผลคุณอาจสามารถดำเนินการการแจ้งเตือน () แบบไดนามิกได้
mathjs ยังเป็นตัวเลือกที่ดีกว่า eval () เพราะมันทำงานในแซนด์บ็อกซ์
ผู้ใช้สามารถลองฉีดรหัส JavaScript ที่เป็นอันตรายผ่านตัวแยกวิเคราะห์นิพจน์ ตัวแยกวิเคราะห์นิพจน์ของ mathjs เสนอสภาพแวดล้อมแบบ sandbox เพื่อดำเนินการนิพจน์ซึ่งจะทำให้สิ่งนี้เป็นไปไม่ได้ เป็นไปได้ว่ามีช่องโหว่ด้านความปลอดภัยที่ไม่รู้จักดังนั้นจึงควรระมัดระวังโดยเฉพาะเมื่ออนุญาตให้มีการประมวลผลนิพจน์โดยพลการ
mathjs รุ่นใหม่กว่านี้ไม่ได้ใช้ eval () หรือ Function ()
parser ป้องกันการเข้าถึงจาวาสคริปต์ภายใน eval และ Function ใหม่ซึ่งเป็นสาเหตุหลักของการโจมตีด้านความปลอดภัย Mathjs เวอร์ชัน 4 และใหม่กว่าไม่ได้ใช้ eval ของ JavaScript ภายใต้ประทุน เวอร์ชัน 3 และเก่ากว่าใช้ eval สำหรับขั้นตอนการคอมไพล์ นี่ไม่ใช่ปัญหาด้านความปลอดภัยโดยตรง แต่ส่งผลให้พื้นผิวการโจมตีมีขนาดใหญ่ขึ้น
การใช้ทั้งการประเมินและการสร้างฟังก์ชั่นใหม่เพื่อรันจาวาสคริปต์นั้นมาพร้อมกับความเสี่ยงด้านความปลอดภัยจำนวนมาก
const script = document.createElement("script");
const stringJquery = '$("#button").on("click", function() {console.log("hit")})';
script.text = stringJquery;
document.body.appendChild(script);
ฉันชอบวิธีนี้ในการใช้งาน Javascript ที่ฉันได้รับเป็นสตริง