Вам нужно добавить "Грант" к этому сценарию в любом случае ...
Greasemonkey 1.0 добавляет специальный императив блока метаданных: @grant.
If a script does not specify any @grant values, Greasemonkey 1.0-1.9 will attempt to auto-detect the right settings. From GreaseMonkey 2.0, @grant none is assumed by default, if no other values are specified.[1]
If a script specifies any values (or they were auto detected), then it will be provided with only those API methods that it declares.
The valid values are unsafeWindow, and the names of those GM_ prefixed values that you wish your script to be granted access to.
Otherwise the script will be granted no special API privileges, and thus run without the security constraints Greasemonkey scripts have traditionally had. If you want your script to operate in this mode, you should explicitly declare @grant none.
Примеры
Для сценариев (более половины, когда они учитывались в последний раз) характерно вообще не использовать никаких специальных API. Для таких сценариев явный запрос на отсутствие специальных привилегий означает, что сценарий будет выполняться непосредственно на странице содержимого. Это означает отсутствие изолированной программной среды безопасности и ее ограничений, поэтому доступ к переменным на странице просто работает, вызов функций и чтение их результатов также работает. Для этого просто:
// ==UserScript==
// @name Grant None Example (can be omitted since GM 2.0)
// @include http*
// @grant none
// ==/UserScript==
console.log('This script grants no special privileges, so it runs without security limitations.');
Если вы используете один из API Greasemonkey, вам следует явно попросить предоставить его вашему сценарию:
// ==UserScript==
// @name Grant Some Example
// @include http*
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
var counter = GM_getValue('counter', 0);
console.log('This script has been run ' + counter + ' times.');
GM_setValue('counter', ++counter);
В этом случае скрипт запрашивает доступ как к GM_getValue
и к GM_setValue
, по одному в каждой строке @grant
. Укажите имя любого API Greasemonkey, которому будет предоставлен доступ к нему. (Все сценарии всегда получают GM_info
без специального запроса.) Временно это также будет работать:
// ==UserScript==
// @name Grant Legacy Example
// @include http*
// ==/UserScript==
var counter = GM_getValue('counter', 0);
console.log('This script has been run ' + counter + ' times.');
GM_setValue('counter', ++counter);
Этот пример будет работать в Greasemonkey версии 1.0. Когда строк @grant нет, Greasemonkey пытается определить, какие API используются, и действует так, как если бы эти строки @grant были указаны. В некоторых случаях это обнаружение может быть неудачным, особенно при использовании eval()
.
Из-за этого все скрипты, написанные до @grant, должны продолжать работать, но вы должны изменить свои скрипты, указав @grant при первой возможности, чтобы они не сломались в будущем.
Уровень совместимости
Многие из API Greasemonkey были продублированы веб-стандартами, такими как DOM Storage. Если вы ожидаете, что ваш скрипт будет работать только в одном домене, вы можете использовать @grant none и его повышенную совместимость без каких-либо недостатков. Просто используйте библиотеку @require для эмуляции API Greasemonkey с помощью стандартных функций браузера:
// ==UserScript==
// @name Grant None Example, With Shim
// @include http://www.example.com/*
// @grant none
// @require https://gist.githubusercontent.com/arantius/3123124/raw/grant-none-shim.js
// ==/UserScript==
var counter = GM_getValue('counter', 0);
console.log('This script has been run ' + counter + ' times.');
GM_setValue('counter', ++counter);
Этот сценарий будет работать так же, как и в примере выше, за исключением того, что грант без ограничений обеспечивает эмуляцию API со стандартными функциями браузера. Когда слой совместимости shim работает достаточно хорошо для вашего сценария, это лучшее из обоих миров.
Объем
В случае отсутствия разрешения пользовательский сценарий по-прежнему имеет собственную глобальную область, отличную от глобальной области страницы содержимого. Это означает, что верхний уровень var x = 1;
не будет виден в области содержимого и, таким образом, не будет разбивать страницу (т. е. если это зависит от переменной x, имеющей другое значение). Чтобы записать значения в область содержимого, выполните window.x = 1;
,
Если вы @require
версию jQuery, она будет неявно назначена window.$
И window.jQuery
. Если страница, на которой вы работаете, зависит от другой версии jQuery, это может привести к поломке страницы. Чтобы обойти эту проблему, в любом месте на верхнем уровне вашего скрипта выполните:
this.$ = this.jQuery = jQuery.noConflict(true);
Этот код сохранит ссылку jQuery (в эту глобальную область действия скрипта при запуске в режиме предоставления без), удалив ее из окна (глобальная область содержимого) и восстановив все, что там изначально хранилось.