Tampermonkey的GM_xmlhttpRequest没有实现'context'属性? [英] Tampermonkey's GM_xmlhttpRequest not implementing 'context' property?

查看:379
本文介绍了Tampermonkey的GM_xmlhttpRequest没有实现'context'属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  Uncaught TypeError:无法读取未定义的属性'profile_url'
未捕获的TypeError:无法读取未定义的属性'encoded_name'

这些错误似乎是引用被调用的 onreadystatechanged 回调 GM_xmlhttpRequest 像这样:

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

函数get_text(e){返回e.innerText || e.textContent; }

函数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,//链接到带有?xml = 1的蒸汽配置文件添加了
accept:'text / xml',
context:{
flair_index:i,
flair_text:text,// span元素的textContent
编码名称:名称,
profile_url:url,//链接到蒸汽profile
query_url:xml_url
},
onreadystatechange:function(response){
if(response.readyState!= 4)
return;
//尝试回退到其他形式的上下文,
//其中任何一个都不起作用response.context适用于Firefox / Greasemonkey
var context = response.context || this.context || context;
var doc = parser.parseFromString(response.responseText,'text / xml');
var validProfile = doc.documentElement.nodeName =='profile';
v ar a = document.createElement('a');
a.href = validProfile?
context.profile_url:// TypeError here,context is undefined
('http://steamcommunity.com/actions/SearchFriends?K='+ context.encoded_name);
.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);
}
});
}

该函数本身称为罚款,并且调用回调,但是一旦我尝试访问其中的上下文 var,它是未定义的。



它在Firefox中按预期工作。它所做的是遍历具有flair类的 span 元素,并使用正则表达式检查它们是否包含Steam用户名,如果是,则使其成为它们的链接Steam社区页面。 ( github )的完整源代码)。该脚本在 / r / PaydayTheHeistOnline 上运行。



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

解决方案

更新:

Tampermonkey现在报告此功能从版本3.8.4116(目前处于测试版)是固定的。请参阅:


  • 错误报告 更改日志

    $ b $ b

    旧的/通用的解决方法:

    上下文属性是Firefox中的 GM_xmlhttpRequest()的一个相对新特性。我怀疑它是否已经在Tampermonkey中实现了;请参阅 Tampermonkey关于的文档> GM_xmlhttpRequest()


    与此同时,这种方法的尝试和真正的方法是使用闭包



    将您的 GM_xmlhttpRequest()

     (function(flair_index,flair_text,encoded_name,profile_url,query_url){
    GM_xmlhttpRequest({
    method:'GET',
    url:xml_url,//链接到带有?xml = 1的蒸汽配置文件添加了
    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);
    .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,// span元素
    名称,
    url的textContent,//链接到蒸汽配置文件
    xml_url
    );


    I have written a UserScript for Greasemonkey (Firefox) and am testing it for compatibility with Chrome's Tampermonkey, and getting errors in the developer console:

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

    The errors seem to be referencing the onreadystatechanged callback of GM_xmlhttpRequest which is called like this:

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

    The function itself is called fine, and the callback is invoked, but once I try to access the context var inside it, it's undefined.

    It all works as expected in Firefox. What it does is iterating over span elements that have the "flair" class and checking with a regex if they contain a Steam username, and if so, makes it a link to their SteamCommunity page. (Full source on github). The script runs on /r/PaydayTheHeistOnline.

    I have tested using an array defined outside the function to store the data instead of using the context property passed to xmlhttpRequest, but I'm getting the exact same error.

    解决方案

    Update:
    Tampermonkey now reports that this feature is fixed as of version 3.8.4116 (in beta at the moment). See:


    Older/generic workaround:
    The context property is a relatively new feature of GM_xmlhttpRequest(), in Firefox. I doubt it's been implemented in Tampermonkey yet; see Tampermonkey's docs for GM_xmlhttpRequest().

    Meanwhile, the tried-and-true method for this kind of thing is to use a closure.

    Change your GM_xmlhttpRequest() call to something like:

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

    这篇关于Tampermonkey的GM_xmlhttpRequest没有实现'context'属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆