Обход неопределенной переменной - PullRequest
2 голосов
/ 22 января 2012

Этот сайт, к которому я пытаюсь получить доступ, имеет

  <script type="text/javascript">
function setCanvasSize()
{
  FB.Canvas.setAutoResize(false);
  FB.Canvas.setSize({ "width": 760, "height": 730 });
}
window.fbAsyncInit = function() {
  setCanvasSize();
}
$(document).ready(function() {
  setCanvasSize();
});

на главной странице, однако FB не определен, потому что у меня заблокирован Facebook в файле hosts.

Всякий раз, когда я пытаюсь получить к нему доступ, он выдает ошибку Uncaught ReferenceError: FB is not defined, и я вижу пустую страницу.

Я попытался установить var FB = 0; с помощью скрипта greasemonkey для страницы, однако это не сработало. Кто-нибудь знает, как я могу обойти это? Есть ли способ удалить этот javascript со страницы с помощью greasemonkey?

Ответы [ 4 ]

1 голос
/ 22 января 2012

Не вижу другого выбора, кроме как "перезаписать" этот объект, когда он не существует.

Поместите этот код в самый конец вашей страницы:

if (typeof FB == "undefined" || !FB) {
    FB = { 
        Canvas: {
            setAutoResize: function() {}, 
            setSize: function() {}
        }
    };
}

Таким образом, код в $(document).ready() будет использовать этот фиктивный объект и не потерпит крах.

0 голосов
/ 22 января 2012

Вам необходимо использовать и @run-at document-start, и unsafeWindow, например, так:

// ==UserScript==
// @name    _Ensure that setCanvasSize or FB is defined
// @include YOUR_SITE/YOUR_PATH
// @run-at  document-start
// ==/UserScript==

unsafeWindow.FB = { 
    Canvas: {
        setSize:        function () {},
        setAutoResize:  function () {} 
    }
};


Остерегайтесь того, что скрипт GM запустится до того, как станет доступен DOM, поэтому попытайтесь манипулировать DOM илидаже alert() или console.log() может привести к сбою сценария.

Впрочем, просто установить объекты JS, как и приведенный мной сценарий.

0 голосов
/ 22 января 2012

Здесь я вижу 2 вопроса.

Во-первых, установка FB = 0 предотвратит ошибку при доступе к FB.Canvas, но любые методы доступа к FB.Canvas, например FB.Canvas.setAutoResize, все равно будут выдавать ошибку.

Во-вторых, все это, вероятно, происходит до того, как ваш скрипт GreaseMonkey выполняется.


Изменить:

Вам нужно использовать @run_at document_start. Подробнее см. http://wiki.greasespot.net/Metadata_Block#.40run-at и https://github.com/greasemonkey/greasemonkey/issues/1103. Доступно с GreaseMonkey 0.9.8+. Затем используйте фиктивные объекты, предоставленные Shadow Wizard в его ответе.

Также убедитесь, что вы правильно взаимодействуете с окном контента, а не с областью действия GreaseMonkey. Это работает, но согласно встроенным комментариям и комментариям ниже - это требует некоторых мер безопасности!

// ==UserScript==
// @name           Mock Facebook
// @namespace      ...
// @include        ...
// @run-at         document-start
// ==/UserScript==

// DO NOT DO THIS - EXAMPLE ONLY - SEE http://wiki.greasespot.net/UnsafeWindow

unsafeWindow.FB = {
    Canvas: {
        setAutoResize: function(){},
        setSize: function(){}
    }
};

Требуется дополнительная работа, чтобы обойти небезопасные unsafeWindow, но это рабочий пример, который, как мы надеемся, может быть должным образом расширен вами или кем-то еще. (Я пробовал оба http://wiki.greasespot.net/Content_Script_Injection и http://wiki.greasespot.net/Content_Script_Injection,, но ни один из них не сработал - возможно, снова из-за проблем со временем. Я также могу вернуться к этому позже.) Кроме того, обязательно заполните соответствующие @namespace и @include.

Нет необходимости сначала проверять существующую переменную FB, так как на самом деле не существует способа, которым она могла бы существовать в противном случае - поэтому нет необходимости перезаписывать что-либо.


В противном случае, единственное решение, о котором я могу сразу подумать, - это расширение Firefox, которое предоставляет фиктивный FB объект в области видимости страницы даже до загрузки страниц.

0 голосов
/ 22 января 2012
window.setCanvasSize = '';
function setCanvasSize()
{
      try {
          FB.Canvas.setAutoResize(false);
          FB.Canvas.setSize({ "width": 760, "height": 730 });
          }
          catch (e) {}
}

Попробуйте это

...