如何将标识符替换为其关联值以进行异地评估?
How to replace identifiers with their associated values for off-site evaluation?
我想要一个标签:
<script src="https://mysource.com/script?foo=bar"></script>
https://mysource.com/script 是一个云函数端点,returns 一个脚本应该 运行 在浏览器中使用 bar
作为 foo
的值。该脚本无法评估函数并简单地发回结果,因为它的预期行为会导致副作用,例如向 window 对象添加东西。
我可以通过以下方式做到这一点:
//prevents code injection like eval("evilcode")
function sanitize(){}
const foo = sanitize(req.query.foo);
const myFunc = ()=>{... <uses foo somewhere> ... <causes side effects> ...};
let strFunction = myFunc.toString();
strFunction = strFunction.replace("foo", foo);
const script = "("+strFunction+")();";
res.status(200).send(script);
但我不禁想知道是否有更好的方法来做到这一点。 Google 做了我想在他们的 gtag 脚本中做的事情。如果您转到 https://www.googletagmanager.com/gtag/js?id=AW-950577603 和 ctrl+f AW-950577603,您会看到查询的 ID (AW-950577603) 出现在 javascript 代码中。但我不知道他们所做的是否正是我正在做的,或者他们是否以更好的方式完成了。建议?
您的代码:
const myFunc = ()=>{... <uses foo somewhere> ... <causes side effects> ...};
let strFunction = myFunc.toString();
strFunction = strFunction.replace("foo", foo);
const script = "("+strFunction+")();";
您可以将 foo
设为参数,而不是文本替换 foo
:
const myFunc = (foo)=>{... <uses foo somewhere> ... <causes side effects> ...};
let strFunction = myFunc.toString();
const script = "("+strFunction+")("+foo+");";
您的代码:
//prevents code injection like eval("evilcode")
function sanitize(){}
const foo = sanitize(req.query.foo);
如果您希望 req.query.foo
显示为 JavaScript 字符串文字,那么 JSON.stringify
通常有效:
const foo = JSON.stringify(req.query.foo);
通常,我会将我的客户端 JavaScript 代码存储在一个单独的文件中。将客户端和服务器端分开 JavaScript 有助于我维护我的代码。在您的情况下,该文件可以公开一个名为 initializeMyApp
的函数,并且您可以使用另一个答案中解释的 动态创建对 initializeMyApp
的调用。例如:
let strFunction = fs.readFileSync("initializeMyApp.js", "utf-8");
const script = "("+strFunction+")("+foo+");";
甚至更好:将您的客户端 JavaScript 代码存储在一个单独的文件中,并将其作为静态内容提供(可能使用 CDN)。然后让客户端代码在单独的 <script>
:
中调用 initializeMyApp
<script src="https://mysource.com/script"></script>
<script>initializeMyApp("bar");</script>
我想要一个标签:
<script src="https://mysource.com/script?foo=bar"></script>
https://mysource.com/script 是一个云函数端点,returns 一个脚本应该 运行 在浏览器中使用 bar
作为 foo
的值。该脚本无法评估函数并简单地发回结果,因为它的预期行为会导致副作用,例如向 window 对象添加东西。
我可以通过以下方式做到这一点:
//prevents code injection like eval("evilcode")
function sanitize(){}
const foo = sanitize(req.query.foo);
const myFunc = ()=>{... <uses foo somewhere> ... <causes side effects> ...};
let strFunction = myFunc.toString();
strFunction = strFunction.replace("foo", foo);
const script = "("+strFunction+")();";
res.status(200).send(script);
但我不禁想知道是否有更好的方法来做到这一点。 Google 做了我想在他们的 gtag 脚本中做的事情。如果您转到 https://www.googletagmanager.com/gtag/js?id=AW-950577603 和 ctrl+f AW-950577603,您会看到查询的 ID (AW-950577603) 出现在 javascript 代码中。但我不知道他们所做的是否正是我正在做的,或者他们是否以更好的方式完成了。建议?
您的代码:
const myFunc = ()=>{... <uses foo somewhere> ... <causes side effects> ...};
let strFunction = myFunc.toString();
strFunction = strFunction.replace("foo", foo);
const script = "("+strFunction+")();";
您可以将 foo
设为参数,而不是文本替换 foo
:
const myFunc = (foo)=>{... <uses foo somewhere> ... <causes side effects> ...};
let strFunction = myFunc.toString();
const script = "("+strFunction+")("+foo+");";
您的代码:
//prevents code injection like eval("evilcode")
function sanitize(){}
const foo = sanitize(req.query.foo);
如果您希望 req.query.foo
显示为 JavaScript 字符串文字,那么 JSON.stringify
通常有效:
const foo = JSON.stringify(req.query.foo);
通常,我会将我的客户端 JavaScript 代码存储在一个单独的文件中。将客户端和服务器端分开 JavaScript 有助于我维护我的代码。在您的情况下,该文件可以公开一个名为 initializeMyApp
的函数,并且您可以使用另一个答案中解释的 initializeMyApp
的调用。例如:
let strFunction = fs.readFileSync("initializeMyApp.js", "utf-8");
const script = "("+strFunction+")("+foo+");";
甚至更好:将您的客户端 JavaScript 代码存储在一个单独的文件中,并将其作为静态内容提供(可能使用 CDN)。然后让客户端代码在单独的 <script>
:
initializeMyApp
<script src="https://mysource.com/script"></script>
<script>initializeMyApp("bar");</script>