Jquery 关闭“@grant none”会破坏我的Greasemonkey脚本吗?

Jquery 关闭“@grant none”会破坏我的Greasemonkey脚本吗?,jquery,facebook,greasemonkey,sandbox,Jquery,Facebook,Greasemonkey,Sandbox,我在Facebook主页上运行这个脚本。它从底部的dock中获取所有对话,并获取它们的\uufb\u令牌 // ==UserScript== // @name MyScript // @namespace MyNameSpance // @include /https?://(www.)?facebook.com(/.*)?/ // @require http://code.jquery.com/jquery-2.1.0.min.js // @version 0.0.0 // @grant no

我在Facebook主页上运行这个脚本。它从底部的dock中获取所有对话,并获取它们的
\uufb\u令牌

// ==UserScript==
// @name MyScript
// @namespace MyNameSpance
// @include /https?://(www.)?facebook.com(/.*)?/
// @require http://code.jquery.com/jquery-2.1.0.min.js
// @version 0.0.0
// @grant none
// ==/UserScript==
(function () {
  // Don't run on frames or iframes
  if (window.top != window.self) {
    return ;
  }

  window.addEventListener('load', function () {

    var element = $('.fbNubGroup.clearfix.videoCallEnabled');
    console.log('SCRIPT ELEMENT: ', element); // is displayed on the console

    var children = element.children();
    console.log('SCRIPT CHILDREN: ', children); // is displayed on the console

    for (var i = 0; i < children.length; i++) {
      var child = $(children[i]);
      console.log('SCRIPT CHILD: ', child); // is displayed on the console

      /*
      child :
        Object [div.someClasses]
          + 0: div.someClasses
            + __FB_TOKEN: [ 267 ]
      */

      console.log('SCRIPT CHILD[0]: ', child[0]); // is displayed on the console
      console.log('SCRIPT CHILD[0].__FB_TOKEN:', child[0].__FB_TOKEN); // UNDEFINED

      var key = child[0].__FB_TOKEN[0];
      console.log('SCRIPT KEY: ', key); // not displayed
    }
  }, false);
}) ();
/==UserScript==
//@name MyScript
//@namespace-MyNameSpance
//@include/https?:/(www.)?facebook.com(/*)/
//@需要http://code.jquery.com/jquery-2.1.0.min.js
//@version 0.0.0
//@grant none
//==/UserScript==
(功能(){
//不要在帧或iFrame上运行
if(window.top!=window.self){
返回;
}
window.addEventListener('load',函数(){
var元素=$('.fbNubGroup.clearfix.videoCallEnabled');
console.log('SCRIPT ELEMENT:',ELEMENT);//显示在控制台上
var children=element.children();
console.log('SCRIPT CHILDREN:',CHILDREN);//显示在控制台上
对于(变量i=0;i

使用
@grant none
,它可以按预期工作,我得到:


但是,如果我将
@grant none
更改为
@grant GM_xmlhttpRequest
,脚本将不再工作。它给出:

并在
子项[0]上引发异常。\uuu FB\u令牌


我不明白为什么,因为
子项[0]
没有更改:


为什么更改
@grant none
会破坏脚本?

当您从
@grant none
切换到
@grant GM\u xmlhttpRequest
时。
(坦率地说,所有通用汽车的开发人员和脚本都应该始终在沙箱上运行——除了极少数例外。这避免了“定时炸弹”编码问题和类似问题的麻烦。)

JavaScript对象、数组、变量和函数不能跨越沙箱。但是,
unsafeWindow
作为一种有限的解决方法提供给Greasemonkey范围

对于这个问题也很重要:

  • jQuery是一种特殊情况,在沙箱中引入非DOM对象非常困难
  • 解决方案:
  • 由于
    \uuufb\u令牌
    是一个数组,因此必须使用
    unsafeWindow
    使其穿过沙箱
  • 在这种情况下尝试使用jQuery会产生令人难以接受的高头痛-结果比率;因此,请使用普通DOM方法
  • 将所有这些放在一起,脚本将变成:

    // ==UserScript==
    // @name        _MyScript
    // @namespace   MyNameSpace
    // @include     /https?://(www.)?facebook.com(/.*)?/
    // @require     http://code.jquery.com/jquery-2.1.0.min.js
    // @version     0.0.0
    // @grant       GM_xmlhttpRequest
    // ==/UserScript==
    (function () {
        // Don't run on frames or iframes
        if (window.top != window.self) {
            return;
        }
        window.addEventListener ('load', function () {
            /*--- This unsafeWindow is key. After that, don't use any jQuery
                while trying to get at javascript objects like __FB_TOKEN.
            */
            var element = unsafeWindow.document.querySelector (
                '.fbNubGroup.clearfix.videoCallEnabled'
            );
            /*-- Used console.info to make it easier to spot messages buried
                in all the Facebook console crud.
            */
            console.info ('SCRIPT ELEMENT: ', element);
    
            var children = element.children;
            console.info ('SCRIPT CHILDREN: ', children);
    
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                console.info ('SCRIPT CHILD: ', child);
    
                /*
                child :
                  Object [div.someClasses]
                    + 0: div.someClasses
                      + __FB_TOKEN: [ 267 ]
                */
                console.info ('SCRIPT CHILD: ', child);
                console.info ('SCRIPT CHILD.__FB_TOKEN:', child.__FB_TOKEN);
    
                var key = child.__FB_TOKEN[0];
                console.info ('SCRIPT KEY: ', key);
            }
        }, false);
    } ) ();
    
    /==UserScript==
    //@name\u MyScript
    //@namespace-MyNameSpace
    //@include/https?:/(www.)?facebook.com(/*)/
    //@需要http://code.jquery.com/jquery-2.1.0.min.js
    //@version 0.0.0
    //@grant GM_xmlhttpRequest
    //==/UserScript==
    (功能(){
    //不要在帧或iFrame上运行
    if(window.top!=window.self){
    返回;
    }
    window.addEventListener('load',函数(){
    /*---此非安全窗口是关键。在此之后,不要使用任何jQuery
    在尝试获取javascript对象时,比如_FB_TOKEN。
    */
    var元素=unsafeWindow.document.querySelector(
    “.fbNubGroup.clearfix.videoCallEnabled”
    );
    /*--使用console.info可以更容易地发现隐藏的消息
    在所有的Facebook控制台中都有crud。
    */
    console.info('SCRIPT元素:',元素);
    var children=element.children;
    console.info('脚本子项:',子项);
    对于(变量i=0;i
    非常感谢您提供了这么高的精度。首先,你知道为什么Chrome不受沙箱的影响吗?我的意思是,这不是我真正的脚本,但是这个逻辑在一个更大的脚本中使用。在Chrome中,从none切换到GM_xml。。。不会更改任何内容,我的脚本正在运行(我没有为此脚本进行测试)第二,我听说过沙箱,但我不知道它的后果,谢谢你最后,作为我的快速修复(并且因为我现在已经大量使用jQuery,我最终使用了
    element=$(unsafeWindow.document.querySelector('.fbNubGroup.clearfix.videoCallEnabled'))在Chrome中你使用的是Tampermonkey吗?Chrome sandbox与FF sandbox非常不同。Chrome+Tampermonkey试图模仿FF+GM,但它不是一个精确的匹配,并且会根据……很高兴,
    $(unsafeWindow…
    现在起作用,但这种方法很可能会在将来导致更多的Headscratcher。)我使用的是Tampermoney,是的。我确实注意到它与Greasemonkey不同(例如,facebook主页上的window.load事件不是同时触发的。我必须使用$(文档)。在Tampermonkey上准备好让脚本等待足够长的时间。)--对$(…)这只是一个快速修复。我将在不久的将来删除关于jQuery的所有内容!再次感谢您的精确性!!您不需要删除所有jQuery。只是不要将其用作提取目标页面定义的javascript变量的一部分。