【问题标题】:Capturing the anchor tag捕获锚标记
【发布时间】:2016-07-03 21:29:20
【问题描述】:

我编写了一个覆盖原生 alert() 方法的 JavaScript 代码。 我需要捕获包含 alert() 执行代码的 HTML 元素。 前两个案例是例子。我已经在 console.log 中打印了元素。

案例 1 - 捕获<script> 标签:

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

JS:

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

案例 2 - 捕获&lt;img&gt; 标签:

HTML: &lt;img src='1' onerror="alert(1)"&gt;

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>
}

案例问题 - 捕获&lt;a&gt; 标签:

HTML: &lt;a href="javascript:alert(1);"&gt;Click here for alert&lt;/a&gt;

JS:

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

请不要建议我通过包含 &lt;a&gt; 或类似的 ID 来修改 HTML。考虑到 HTML 是纯静态的,我无法修改任何内容。我可以只添加一个 JavaScript,但我只是想知道如何做到这一点。

【问题讨论】:

  • 你可以做类似的事情。唯一的区别是点击锚点加载新页面(通常)。选中 Google 开发工具中的“保留日志”复选框以查看来自之前页面的消息。
  • "请不要建议我修改 HTML","考虑到 HTML 是纯静态的,我不能修改任何东西。" &lt;a&gt;元素不包含html或者文字内容怎么点击&lt;a href="javascript:alert(1);"&gt;&lt;/a&gt;
  • @AlexKudryashev 不不,应用程序将在客户端运行。我需要仅使用 JS 找到&lt;a&gt; 元素,并将必要的数据从客户端发送到服务器。
  • @guest271314 抱歉,错过了要点击的内容。现已编辑。

标签: javascript html overriding


【解决方案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;
})();
&lt;a href="javascript:alert(1);"&gt;test&lt;/a&gt;

【讨论】:

  • +1 这有帮助。谢谢。有没有更简单的解决方案?比如,从 alert() 遍历到 href,从 href 遍历到 &lt;a&gt;?相似的东西?而且,我没有得到你提到的 eval() 东西。你能详细说明一下吗?
  • 可能会解析警报( --- parse this --- ),以便您可以对请求执行某些操作,例如作为 console.log() 它。基本解析会记录调用的文本,并且可以正常翻译 alert("hi"),但您也可以使用 eval() 来处理 alter(1+1)。 Eval 可能有点危险,所以我自己倾向于回避它,但它可能是你可以利用的东西。
【解决方案2】:

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

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();

});
&lt;a href="javascript:alert(1);"&gt;&lt;/a&gt;

【讨论】:

  • +1 感谢您的回答。但是,这不适合通用查找。我的意思是,HTML 中可以有任何东西 - alert(1)、alert('anything')、[all kind of pop-ups] 我需要一个通用的解决方案,类似于案例 1 和 2。
  • @unix_root "但是,这不适合通用查找。我的意思是,HTML 中可以有任何内容 - alert(1)、alert('anything')," 使用RegExp /\(|\)/g 时,哪种情况不会返回预期结果?
  • 您能否在正则表达式代码中添加一些文档?我不明白。
  • @unix_root 第一个RegExp用空字符串替换javascript;第二个RegExp 尝试通过匹配单词后跟( 和函数参数(1) 来捕获函数名称,包括括号;第三个RegExp 用空字符串替换第二个捕获组、函数参数处的括号;参数1被设置为matches[1]的替换字符串值
【解决方案3】:

不要使用 href 属性调用 JavaScript。应该避免。不推荐使用。请改用 onclick 事件。见这里:https://stackoverflow.com/a/10242595/5969411

<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。

【讨论】:

  • 是的,我明白了。但是,这属于案例 2 - 使用事件。对于问题中给出的确切情况,我需要某种解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-21
  • 2010-12-07
  • 2020-05-31
  • 2021-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多