javascript - Tampermonkey 的 GM_xmlhttpRequest 未实现 'context' 属性?

标签 javascript google-chrome tampermonkey gm-xmlhttprequest

我已经为 Greasemonkey (Firefox) 编写了一个用户脚本,并正在测试它与 Chrome 的 Tampermonkey 的兼容性,并在开发者控制台中收到错误:

Uncaught TypeError: Cannot read property 'profile_url' of undefined
Uncaught TypeError: Cannot read property 'encoded_name' of undefined

这些错误似乎引用了 GM_xmlhttpRequestonreadystatechanged 回调,其调用方式如下:

var flairs = document.querySelectorAll('span.flair');
var steam_re = /(?:(?:https?:\/\/)?www\.)?(?:steam|pc)(?:community\.com\/?(?:(id|profiles)\/?)?|[\s\-_]*id)?[\/:\s\|]*(.{2,}?)(?:[\/|:\-\[(] ?(?:\/?(?:ghost|enforcer|tech|mm|master))+[\[)]?)?$/i

function get_text(e) { return e.innerText || e.textContent; }

function set_text(e, t) {
    if (e.innerText)
        e.innerText = t;
    else
        e.textContent = t;
}

var parser = new DOMParser();

for (var i = 0; i < flairs.length; i++) {
    var text = get_text(flairs[i]);
    var match = steam_re.exec(text);
    if (match == null || match.length < 3)
        continue;
    var type = match[1] || 'id';
    var name = encodeURIComponent(match[2]);
    var url = 'http://steamcommunity.com/' + type + '/' + name;
    var xml_url = url + '?xml=1';
    GM_xmlhttpRequest({
        method: 'GET',
        url: xml_url, // Link to a steam profile with ?xml=1 added
        accept: 'text/xml',
        context: {
            flair_index: i,
            flair_text: text, // textContent of span element
            encoded_name: name,
            profile_url: url, // Link to steam profile
            query_url: xml_url
        },
        onreadystatechange: function(response) {
            if (response.readyState != 4)
                return;
            // Attempt to fall back to alternate forms of context,
            // none of which works. response.context works on Firefox/Greasemonkey.
            var context = response.context || this.context || context;
            var doc = parser.parseFromString(response.responseText, 'text/xml');
            var validProfile = doc.documentElement.nodeName == 'profile';
            var a = document.createElement('a');
            a.href = validProfile ?
                context.profile_url : // TypeError here, context is undefined
                ('http://steamcommunity.com/actions/SearchFriends?K=' + context.encoded_name);
            a.className += (validProfile ? 'steam-profile-link' : 'steam-profile-search-link');
            var a_text = document.createTextNode(context.flair_text);
            a.appendChild(a_text);
            set_text(flairs[context.flair_index], '');
            flairs[context.flair_index].appendChild(a);
        }
    });
}

函数本身被很好地调用,并且调用了回调,但是一旦我尝试访问其中的 context var,它就未定义。

一切都在 Firefox 中按预期运行。它的作用是迭代具有“flair”类的 span 元素,并使用正则表达式检查它们是否包含 Steam 用户名,如果包含,则使其成为 SteamCommunity 页面的链接。 (完整来源github)。该脚本在 /r/PaydayTheHeistOnline 上运行.

我已经测试过使用函数外部定义的数组来存储数据,而不是使用传递给 xmlhttpRequest 的上下文属性,但我得到了完全相同的错误。

最佳答案

更新:
Tampermonkey 现在报告称,该功能已于 3.8.4116 版(目前处于测试版)中修复。请参阅:


旧/通用解决方法:
The context property is a relatively new feature of GM_xmlhttpRequest(), in Firefox 。我怀疑它是否已在 Tampermonkey 中实现;请参阅Tampermonkey's docs for GM_xmlhttpRequest() .

同时,解决此类问题的行之有效的方法是使用 closure .

将您的 GM_xmlhttpRequest() 调用更改为如下:

( function (flair_index, flair_text, encoded_name, profile_url, query_url) {
    GM_xmlhttpRequest ( {
        method: 'GET',
        url:    xml_url, // Link to a steam profile with ?xml=1 added
        accept: 'text/xml',
        onreadystatechange: function (response) {
            if (response.readyState != 4)
                return;

            var doc = parser.parseFromString (response.responseText, 'text/xml');
            var validProfile = doc.documentElement.nodeName == 'profile';
            var a = document.createElement ('a');
            a.href = validProfile ?
                profile_url : 
                ('http://steamcommunity.com/actions/SearchFriends?K=' + encoded_name);
            a.className += (validProfile ? 'steam-profile-link' : 'steam-profile-search-link');
            var a_text = document.createTextNode (flair_text);
            a.appendChild (a_text);
            set_text (flairs[flair_index], '');
            flairs[flair_index].appendChild (a);
        }
    } );
} ) (
    i,
    text, // textContent of span element
    name,
    url, // Link to steam profile
    xml_url
);

关于javascript - Tampermonkey 的 GM_xmlhttpRequest 未实现 'context' 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18435241/

相关文章:

javascript - Tampermonkey 替换 window.onload

javascript - Tampermonkey,在点击事件上从附加的 DOM 对象调用用户脚本函数

javascript - 用户脚本访问动态生成的(Vaadin 框架)内容

javascript - 传递/传入导致异常的 URL 字符串

javascript - 将简单的 php Web 应用程序转换为仅 LAN

javascript - 如何减少并改进丑陋的 JavaScript 代码?

css - 输入 :focus on css between chorme and mozilla 的不同工作

google-chrome - 使用 cmd 为 Chrome 浏览器启用开发者模式扩展

javascript - Php为什么不向Jquery ajax发送响应?

javascript - 在 Dev Tools -> Resources -> Frames 下获取 Element