在某些情况下,表单属性“未定义”错误,而其他情况则不然

时间:2012-10-31 18:11:51

标签: javascript forms firefox greasemonkey

我创建了以下greasemonkey脚本,以自动跳过蒸汽年龄检查页面:

// ==UserScript==
// ...
// @include     http://store.steampowered.com/agecheck/*
// ==/UserScript==

//Mini script for doing steam age checks automatically
if( document.URL.indexOf('agecheck') > -1 )
{
    var form = document.getElementById('agegate_box').getElementsByTagName('form')[0];
    form.ageDay.value = 18;
    form.ageMonth.value = 'August';
    form.ageYear.value = 1987;
    form.submit();
}

此类网页的一个示例是:http://store.steampowered.com/agecheck/app/16730/。请注意,如果您设置了store.steampowered.com“出生时间”Cookie,此页面将自动跳到游戏中,因此您可能必须先删除它。

当在Windows XP上运行的Firefox 17.0(beta)上安装此greasemonkey脚本时,它可以正常工作。

然后我在我的Windows 7机器上安装了该脚本,该机器运行最新的FF(16)。在此计算机上,访问form.ageDay时脚本会中断。错误控制台显示:

Error: form.ageDay is undefined

更奇怪的是,如果我只是将我的脚本粘贴到Firefox Scratchpad(Shift + F4)并执行它,它就可以查找并提交表单。

在XP上,GM脚本是如何工作的,在Win7中脚本可以在暂存器中工作,但在Win7上,脚本在GM中不起作用?

另一个奇怪的是,在Win7机器上,如果我激活Firebug,var form显然有'ageDay'属性,但是watch表达式返回undefined?

enter image description here

1 个答案:

答案 0 :(得分:1)

该代码在Windows XP或Windows 7上对我不起作用。也不应该这样。 GM脚本不能(通常)使用这样的命名表单对象。请参阅Greasemonkey Pitfall: Named Forms and Form Elements

使用沙盒安全(以及更强大的)方法来获取这些表单元素。例如,querySelector()。此脚本适用于您链接的页面:

// ==UserScript==
// @name        _delme 677
// @include     http://store.steampowered.com/agecheck/*
// @grant       GM_xmlhttpRequest
// ==/UserScript==

//Mini script for doing steam age checks automatically
if (/agecheck/i.test (location.pathname) ) {
    var ageForm = document.querySelector ("#agegate_box form");
    ageForm.querySelector ("[name='ageDay']").value     = 18;
    ageForm.querySelector ("[name='ageMonth']").value   = 'August';
    ageForm.querySelector ("[name='ageYear']").value    = 1987;
    ageForm.submit ();
}

注意:

  1. Firefox Scratchpad之所以有效,是因为它没有被GM沙箱隔离。
  2. 至于为什么它似乎适用于Win XP,这很可能是一个侥幸 - 它在XP上对我不起作用,它不应该。

    对于某些@grant none方案,这种代码可能有效。 (@grant none默认情况下会在很多情况下应用;请参阅文档。)

    或者可能有多个版本的脚本正在运行,甚至FF已损坏且需要重新启动。

    底线,不要那样编码。

  3. 至于but the watch expression returns undefined? ......这只是工作中的沙箱隔离,在XP上看起来与我一样。

  4. 代码,如上所述使用querySelector()几乎可以处理用户可能遇到的每个页面,它肯定适用于此问题的参数。但它目前不适用于某些可能的 HTML5表单以及某些网站据称曾使用过的 无效 HTML。

    在这两种情况下,我在上面提到的陷阱链接中提到的代码,尽管存在某些无效的HTML或尖端的HTML5,但仍然有效。

    具体来说,这种代码虽然不如querySelector灵活,但可以使用更广泛的场景(即使它们是无效的HTML):

    if (/agecheck/i.test (location.pathname) ) {
        var ageForm = document.querySelector ("#agegate_box form");
        ageForm.elements.namedItem ('ageDay').value     = 18;
        ageForm.elements.namedItem ('ageMonth').value   = 'August';
        ageForm.elements.namedItem ('ageYear').value    = 1987;
        ageForm.submit ();
    }