捕获锚点标签

3

我编写了一段JavaScript代码,覆盖了原生的alert()方法。 我需要捕获包含alert()执行代码的HTML元素。 前两种情况是示例。 我在console.log中打印了这些元素。

情况1 - 捕获<script>标签:

HTML: <script> alert(1); </script>

JS:

window.alert = function()
{ 
    console.log(document.currentScript); // <script> is printed
}

案例2 - 捕获 <img> 标签:

HTML: <img src='1' onerror="alert(1)">

JS:

window.alert = function()
{ 
    console.log(arguments.callee.caller.arguments[0].target);
    // arguments.callee --> console.log()
    // arguments.callee.caller --> onerror(event) {}
    // arguments.callee.caller.arguments[0] --> event
    // arguments.callee.caller.arguments[0].target --> <img>
}
案例问题 - 捕获标签:

HTML: <a href="javascript:alert(1);">点击这里弹出警告</a>

JS:

window.alert = function()
{ 
    console.log( // how to find <a> element) 
}

请不要建议我通过包含<a>的ID来修改HTML或类似的方式。请考虑HTML是纯静态的,我无法进行任何修改。我只能添加JavaScript,并且我只想知道如何做到这一点。

你可以做类似的事情。唯一的区别是,通常情况下,单击锚会加载新页面。在Google Dev工具中勾选“保留日志”复选框,以查看来自先前页面的消息。 - Alex Kudryashev
1
请不要建议我修改HTML。请考虑HTML是纯静态的,我无法修改任何内容。如何点击{{link1:元素,其中元素不包含要点击的<a href="javascript:alert(1);"> HTML或文本内容? - guest271314
@AlexKudryashev 不是的,应用程序将在客户端运行。我需要使用JS仅查找<a>元素,并从客户端发送必要的数据到服务器。 - verstappen_doodle
@ guest271314 对不起,错过了需要点击的那个东西。现在已经编辑好了。 - verstappen_doodle
3个回答

1
你可能能够找到这样的警报并将它们转换为点击事件。就像这样。请注意,点击事件警报调用可以变得更加复杂,可能使用eval(),但我将冒险留给你。

window.alert = (function(){
  var selected = document.querySelectorAll("a[href^='javascript:alert('");

  Array.from(selected).forEach(function(item){
    var old = item.href
    item.addEventListener("click", function(){ alert(old.substring(11)); });
    item.href="javascript:void(0);";
  });

  var _alert = function(msg) {
    console.log(msg);
    console.log(arguments.callee.caller.arguments[0].target);
  };
  
  return _alert;
})();
<a href="javascript:alert(1);">test</a>


+1 这很有帮助。谢谢。还有更简单的解决方案吗?比如,从 alert() 遍历到 href,然后从 href 遍历到 <a> 标签?有类似的方法吗?另外,我不太理解你提到的 eval()。能详细解释一下吗? - verstappen_doodle
可能可以解析警告(--- 解析这个 ---),以便您可以对请求执行某些操作,例如console.log()。基本解析将记录调用的文本,并且对于翻译alert("hi"),它将正常工作,但是您还可以使用eval()来处理alter(1+1)。Eval可能有点危险,因此我自己倾向于避免使用它,但这可能是您可以利用的东西。 - JonSG

1
你可以在 window 上使用 load 事件; 在选择器 "a[href='javascript:alert(1);']" 上使用 click 事件来获取 href 属性的值; 在 click 处理程序中调用 event.preventDefault(); 使用 String.prototype.match() 创建包含 href 属性值的数组; 全局定义匹配项; 使用 new Function(); 使用 Function.prototype.call()this 设置为 <a> 元素; 使用 .match() 返回的匹配参数调用选择器:<a> 元素上的.click()

window.alert = function() {
  console.log(arguments, this)
}

window.addEventListener("load", function() {

  a = document.querySelector("a[href='javascript:alert(1);']");
  a.addEventListener("click", function(event) {
    event.preventDefault();
    var data = this.href.replace(/javascript/, "");
    matches = data.match(/\w+(?=\()|(\(.*\))/g);
    matches[1] = matches[1].replace(/\(|\)/g, "");
    var fn = new Function(matches[0] + ".call(a, matches[1])");
    fn();
  });

  a.click();

});
<a href="javascript:alert(1);"></a>


+1 感谢您的回答。但是,这并不适用于通用查找。我的意思是,HTML 中可能会有任何内容 - alert(1),alert('anything'),[各种弹出窗口]。我需要一个通用的解决方案,类似于情况 1 和 2。 - verstappen_doodle
@unix_root "但是,这并不适用于通用查找。我的意思是,HTML 中可能会有任何内容 - alert(1),alert('anything')," 哪种情况使用 RegExp /\(|\)/g 不会返回预期结果? - guest271314
你能否给 Regexp 代码添加一些文档说明?我不太理解它。 - verstappen_doodle
1
@unix_root 第一个 RegExp 用空字符串替换 javascript;第二个 RegExp 尝试通过匹配跟随 ( 的单词来捕获函数名,以及包括括号在内的函数参数 (1);第三个 RegExp 用空字符串替换第二个捕获组中的括号,即函数参数;将参数 1 设置为 matches[1] 的替换字符串值。 - guest271314

0

不要使用href属性来调用JavaScript。应该避免这样做。这不是推荐的用法。相反,应该使用onclick事件。请参见此处:https://dev59.com/sWLVa4cB1Zd3GeqP0-tb#10242595

<script>
    window.alert = function(msg, element) {
        console.log('Msg:', msg);
        console.log('Element:', element);
    };
</script>
<a href="#" onclick="alert(1, this);return false;">Test 1</a>
<a href="#" onclick="alert(2, this);return false;">Test 2</a>
<a href="#" onclick="alert(3, this);return false;">Test 3</a>

我在上面的onclick事件中返回了false,以抑制锚点跳转到“#”URL指令,但如果您愿意,您也可以在这里轻松地返回true。


是的,我理解。但这属于第二种情况 - 使用事件。我需要针对问题中给出的确切情况找到某种解决方案。 - verstappen_doodle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接