Devi aggiungere una "concessione" a quello script in qualsiasi modo ...
Greasemonkey 1.0 aggiunge un imperativo speciale per il blocco dei metadati: @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.
Esempi
È comune per gli script (oltre la metà dell'ultimo conteggio) di non utilizzare alcuna API speciale. Per tali script, chiedendo esplicitamente di non concedere privilegi speciali significa che lo script verrà eseguito direttamente nella pagina di contenuto. Ciò significa che non esiste sandbox di sicurezza e nessuna delle sue limitazioni, quindi l'accesso alle variabili nella pagina funziona, chiama le funzioni e legge i risultati anche solo funziona. Per farlo, semplicemente:
// ==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.');
Se usi una delle API di Greasemonkey, devi chiedere esplicitamente che sia concessa al tuo script:
// ==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);
In questo caso, lo script chiede di ottenere l'accesso ad entrambi GM_getValue
e GM_setValue
uno su ciascuno @grant
linea. Specificare il nome di qualsiasi API Greasemonkey per ottenere l'accesso ad essa. (Tutti gli script ottengono sempre GM_info
senza specificarlo esplicitamente.) Temporaneamente, ciò funzionerebbe anche:
// ==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);
Questo esempio funzionerà con Greasemonkey versione 1.0. Quando non ci sono linee @grant, Greasemonkey prova a rilevare quali API vengono utilizzate e si comporta come se fossero state specificate quelle @grant. Questo rilevamento potrebbe fallire in alcuni casi, specialmente quando eval()
viene usato.
Tutti gli script scritti prima di @grant dovrebbero continuare a funzionare a causa di ciò, ma è necessario modificare gli script per specificare @grant al più presto, in modo che non si interrompano in futuro.
Livello di compatibilità
Molte API Greasemonkey sono state duplicate da standard web come DOM Storage. Se ti aspetti che il tuo script funzioni solo su un singolo dominio, puoi utilizzare @grant none e la sua maggiore compatibilità senza inconvenienti immediatamente. Utilizza semplicemente una libreria @require per emulare le API di Greasemonkey con funzionalità browser standard attualmente disponibili:
// ==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);
Questo script funzionerà come nell'esempio precedente, tranne per il fatto che la concessione di Nessuno shim sta fornendo l'emulazione API con funzionalità browser standard. Quando il livello di compatibilità shim funziona abbastanza bene per il tuo script, questo è il meglio di entrambi i mondi.
Scopo
In nessuno caso, lo script utente ha ancora il proprio ambito globale, distinto dall'ambito globale della pagina di contenuto. Ciò significa che un livello superiore var x = 1;
non sarà visibile all'ambito del contenuto e quindi non interromperà la pagina (ad esempio se dipende da una variabile x che ha un valore diverso). Per scrivere valori per l'ambito del contenuto, fare window.x = 1;
.
Se tu @require
una versione di jQuery, sarà assegnata implicitamente a window.$
e window.jQuery
. Se la pagina in cui si esegue dipende da una versione diversa di jQuery, ciò potrebbe interrompere la pagina. Per ovviare a questo problema, ovunque al livello più alto del tuo script fai:
this.$ = this.jQuery = jQuery.noConflict(true);
Questo codice salverà un riferimento a jQuery (in questo, l'ambito globale dello script quando è in esecuzione nella modalità grant grant), rimuovendolo dalla finestra (l'ambito globale del contenuto) e ripristinando qualsiasi cosa originariamente archiviata.