jquery - 关闭 `@grant none` 会破坏我的 Greasemonkey 脚本吗?

标签 jquery facebook greasemonkey sandbox

我在 Facebook 主页上运行这个脚本。它获取底部停靠栏中的所有对话并获取它们的 __FB_TOKEN

// ==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);
}) ();


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

grant_none


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

grant GM_xmlhttpRequest

并在 child[0].__FB_TOKEN 行抛出异常。


我不明白为什么,因为 CHILD[0] 没有改变:

child

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

最佳答案

当您从@grant none 切换到@grant GM_xmlhttpRequest 时,Greasemonkey switches the sandbox back on, as a side-effect .
(坦率地说,无论如何,所有 GM 开发人员和脚本都应该始终在沙盒上运行——除了极少数异常(exception)。这避免了“定时炸弹”编码问题和像这个问题这样令人头疼的问题。)

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

对于这个问题也很重要:

  1. > Greasemonkey (and Firefox) just shut down some of the previously possible solutions using unsafeWindow .
  2. jQuery 是一种特殊情况,很难用于将非 DOM 对象带入沙箱。

解决方案:

  1. 由于 __FB_TOKEN 是一个数组,您必须使用 unsafeWindow 来获取它穿过沙箱。
  2. 在这种情况下尝试使用 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);
} ) ();

关于jquery - 关闭 `@grant none` 会破坏我的 Greasemonkey 脚本吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25222373/

相关文章:

javascript - 您是否需要在 jQuery 的 document.ready 中放置一个 knockout.js 绑定(bind)处理程序

javascript - 如果 var not set 总是结果为真,即使它的设置

jquery - 单击大纲?

facebook - Rails + omniauth + facebook - 检测到 csrf

android - Facebook 聊天机器人 : Animated GIFs in Generic Templates

javascript - 使用 Tampermonkey/javascript 控制 Netflix (HTML5) 播放

javascript - 使用 jQuery 将页面顶部设置为距顶部 340px

facebook - 如何为 facebook 编写特定的应用程序?

javascript - 在没有提示的情况下将图像保存到硬盘?

javascript - 当页面通过 ajax 更改时,如何运行 Greasemonkey 脚本?