如何拦截读取文本输入的值?

时间:2015-04-25 03:24:46

标签: javascript jquery greasemonkey tampermonkey

我正在为各种第三方网站制作一些Greasemonkey / Tampermonkey脚本。 (添加越南文本输入的Unicode规范化,并将字符组合为网站所期望的预组合字符。)

在简单网站上,我已经能够找到他们捕获的事件,通常会在网站脚本处理之前提交并处理文本输入内容。

但是在AJAXy网站上,他们可能会做一些事情,比如在每个按键或计时器上测试输入。 (我不想在输入时更改文本规范化,因为它会影响退格的语义以更改色调标记)。

每次网站脚本尝试从DOM获取输入元素中的文本时,是否有一种方法可以捕获?也许是prototype之类的东西,我之前从未使用过,或者因为它处理DOM /主机对象等而不会这样做?

我目前正在处理的网站似乎总是使用jQuery .val()来获取文本输入的文本值。我猜测至少必须有一些深奥的方法来拦截jQuery,但我真的想知道我在最低级别拦截这个的选择,如果可能的话。

2 个答案:

答案 0 :(得分:2)

您可以通过覆盖<input> value来更改 javascript 看到 2 的页面 - 物业的吸气剂。请注意,这一覆盖也会改变jQuery和其他库看到的内容

Object.defineProperty (HTMLInputElement.prototype, "value", {
    get: function () {
        return "xxx";
        //return this.value;  //-- Warning! This causes infinite recursion.
    }
} );

左下方的代码段显示了一个更实用的示例(仅限Firefox。我认为在Chrome中这样做是可行的方法,没有严重的并发症 - 参见下面提到的bug。)

此示例通常会报告输入值,直到您按下&#34;欺骗&#34;按钮。按&#34;列表&#34;按钮,查看javascript认为输入的值是什么。:

&#13;
&#13;
window.fakeInput = false;

$(document).ready (jQueryMain);

function ListValue (preamble) {
    $("#Output").append ('<li>' + preamble + $("#inpTarg").val() + '</li>');
}

function jQueryMain () {
    //-- This works on Firefox but not Chrome!
    var oldInpValDescriptor = Object.getOwnPropertyDescriptor (HTMLInputElement.prototype, "value");
    if (oldInpValDescriptor == null) {
        // See Chrome issue 43394 and many related.
        alert ('This browser does not support overriding the value property');
        return;
    }
    Object.defineProperty (HTMLInputElement.prototype, "value", {
        get: function () {
            if (window.fakeInput && this.id == "inpTarg") {
                console.log ("Spoofing...");
                return document.getElementById ("inpSpoof").value;
            }

            return oldInpValDescriptor.get.call (this);
        }
    } );

    $("#btnPrint").click ( function () {
        ListValue ('');
    } );

    $("#btnHijack").click ( function () {
        window.fakeInput    = ! window.fakeInput;
        var onOffStr        = window.fakeInput ? "on" : "off";

        if (window.fakeInput)
            $("#btnHijack").text ('Restore Input');
        else
            $("#btnHijack").text ('Hijack Input');

        ListValue ('Hijack ' + onOffStr + '. Value = ');
    } );
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<p>
    <label>Target value:<input type="text" value="I'm not safe!" id="inpTarg"></label> <br>
    <label>Spoof value:<input type="text" value="I'm perfectly fine. ;)" id="inpSpoof"></label>
</p>
<p>
    <button id="btnHijack">Hijack Input</button> <br>
    <button id="btnPrint">List value</button> <br>
</p>
<ol id="Output"></ol>
&#13;
&#13;
&#13;

警告:

  1. 这闻起来像是&#34; x Y&#34;问题。回答问题,但这种方法可能不是解决任何现实问题的最佳方法。
  2. 这不会覆盖HTML表单提交时发送到服务器的内容。目标服务器将看到未加密的值。
  3. 在Greasemonkey / Tampermonkey脚本中,覆盖代码必须在页面范围内运行。即使用@grant none或注入代码。
  4. 目前无法在Chrome中使用!请参阅Issue 43394以及许多相关错误。

答案 1 :(得分:0)

我找到了jQuery案例的答案,但还没有针对低级/非jQuery案例。

<强> jQuery的:

jQuery.valHooks.text = {
  get: function (elem) {
    // check fields of elem if only intercepting specific text elements
    return doSomeTransformation(elem.value);
  }
};

我在a three-year old post on the blog of Rodney Rehm中找到了解决方案,使用了明显未记录的jQuery功能valHooks