我很难理解(-)运算符在JS中用于非数学建议的使用。我有以下代码:
let jeff = (new URL(location).searchParams.get('jeff') || "No parameters.");
eval(`ma = "Ma name ${jeff}"`);
document.write(ma)
和以下URL:
basic.html?jeff=%22-alert(1)-%22
我很难理解警报是如何提高的。谢谢你的帮助。
我希望打印一个字符串,而不是执行alert函数。
除数学外,JavaScript中使用的减法运算符
-
是什么?
这是一个奇怪的问题,但这不是你在这里问的真正的问题。
我很难理解警报是如何发出的。
这个才是我们真正关心的。
如果你不明白这样一个过程是如何工作的,那么一步一步地了解它会有所帮助。
看第一行:
let jeff = (new URL(location).searchParams.get("jeff") || "No parameters.");
URL
构造函数对其第一个参数进行字符串化,并将其解析为URL。location
是保存当前页面URL信息的对象。它被字符串化为完整的URL。searchParams
属性是一个URLSearchParams
对象,它以结构化、解码的方式保存URL的所有查询参数,如?jeff=%22-alert(1)-%22
。.get("jeff")
尝试获取jeff
参数的值
注意url是受编码约束的。%22
是引号字符"
的百分比编码;%2B
是加号+
的百分比编码;+
是单个空格
的URL编码;等等。
如果jeff
参数为空或不存在,则|| "No parameters."
默认为字符串"No parameters."
。如果您的位置是https://example.com/?jeff=%22-alert(1)-%22
,则赋值给变量jeff
的结果是'"-alert(1)-"'
。
二线:
eval(`ma = "Ma name ${jeff}"`);
`ma = "Ma name ${jeff}"`
是一个模板字面值,它将变量jeff
插入到字符串的其余部分;结果字符串是'ma = "Ma name "-alert(1)-""'
。eval
将字符串作为代码执行。因此,这一行实际上是:ma = "Ma name "-alert(1)-""
(或者更简洁一点:ma = "Ma name " - alert(1) - "";
)。
从"Ma name "
中减去alert(1)
,然后从中间结果中减去""
。为了求值,执行alert(1)
。这就是alert
窗口的显示方式。中间结果和最终结果都是NaN
,因为它们涉及alert
的返回值,即undefined
。然后将NaN
赋值给变量ma
。
第三行:
document.write(ma)
这只是将结果NaN
(作为字符串"NaN"
)写入打开的文档流(或者,如果关闭,打开一个新的,然后写入其中)。
运行此代码片段以检查中间结果。注意,eval
和对实际location
的引用在代码片段中被删除了;这只是为了让您大致了解如何检查中间结果。
const locationHref = "https://example.com/?jeff=%22-alert(1)-%22",
urlObject = new URL(locationHref),
searchParams = urlObject.searchParams,
jeffParameter = searchParams.get("jeff"),
jeff = jeffParameter || "No parameters.",
jeffIfNotFound = null || "No parameters.",
interpolatedString = `ma = "Ma name ${jeff}"`;
console.log({
locationHref,
urlObject,
searchParams, // Look at this in your browser console; the Stack Snippet doesn’t show a very useful representation.
jeffParameter,
jeff,
jeffIfNotFound,
interpolatedString
});
.as-console-wrapper { max-height: 100% !important; top: 0; }
回到第一个问题:
除数学外,在JavaScript中使用的减法运算符
-
是什么?
在这段代码中,-
没有什么特别之处。尝试此查询字符串中的任何操作符:?jeff=%22**alert(1)/alert(1)*alert(1)>>>~alert(1)^alert(1)===alert(1)||!alert(1)<%22
,以及更多;这将发出六次警报,结果为毫无意义的1
。
减法运算符仅用于数学运算。任何其他应用程序要么是一个hack,要么是无意义的。
实际上,我尝试了其他操作符,如+ (
+
)
但是你没有正确地进行url编码。
new URLSearchParams("jeff=a+b").get("jeff"); // Result: "a b".
new URLSearchParams("jeff=a%2Bb").get("jeff"); // Result: "a+b".
new URLSearchParams("jeff=a%2Bb%25c%26%26d").get("jeff"); // Result: "a+b%c&&d".
+
的工作方式完全相同。重要的是函数将执行以便求值。如果它们位于运算符的中间,那么它们就是要求值的操作数;使用哪个操作符并不重要(除非它们是短路的,在这种情况下可以跳过求值)。