2008-09-23 285 views

回答

8

通過GM_setValue(keyname, value)將數據存儲爲mozilla首選項值,可以在頁面加載中持久保存數據。

下面是一個簡單的例子,tallys的腳本已經被執行的次數 - 由給定的瀏覽器:

 
var od = GM_getValue("odometer", 0); 
od++; 
GM_setValue("odometer", od); 
GM_log("odometer=" + od); 

GM值類似於在cookie值的cookie只能由起源訪問域,GM值只能由創建它們的腳本訪問。

+0

這真的是一個隱藏的功能,甚至鮮爲人知?它是Greasemonkey記錄的API的一部分,它本身非常小。 – 2008-09-23 14:15:13

+0

同意這本身並不隱藏。但它屬於成語範疇。 – 2008-09-23 14:28:35

+0

是的,通用汽車的API真的不是那麼大,因此我不知道'隱藏的功能'本身 - 詢問有趣的技術/漏洞提供有用的,非顯而易見的功能會更有趣。 – 2008-09-23 15:28:54

3

匿名統計

假設你有一個基本的託管服務,提供訪問日誌,你可以輕鬆地跟蹤您的腳本的基本使用統計信息。

  1. 在您自己的網站上放置一個gif文件(例如,徽標圖像)。
  2. 在腳本中,附加一個img元素引用該GIF的頁面:現在
 
var img = document.createElement("img"); 
img.src = "http://mysite.com/logo.gif"; 
document.body.appendChild(img); 

,每個用戶執行腳本的時候,您的託管服務將註冊在該gif文件一擊。

要跟蹤多個腳本,請爲每個腳本使用不同的gif文件。或者在URL中添加某種區分參數(例如:http://mysite.com/logo.gif?zippyver=1.0)。

+3

...當你在它的時候,你也可以發送他們的用戶名和密碼 – 2008-09-23 14:36:09

+0

請提供代碼示例 – 2008-09-23 14:48:12

+0

我實際上有一個腳本,當安裝腳本時會生成一個僞GUID, GM_setValue,然後每天*腳本運行它會打我的網站,發送查詢字符串中的GUID。我將這些數據記錄到數據庫中以獲取使用情況統計信息。 – 2008-09-23 15:31:33

13

Greasemonkey腳本通常需要搜索頁面上的內容。而不是挖掘DOM,嘗試使用XPath來定位感興趣的節點。 document.evaluate()方法允許您提供XPath表達式並返回一組匹配節點。這是一個不錯的tutorial讓你開始。作爲一個例子,這裏有一個腳本,我寫了導致。中文的帖子鏈接在新標籤中打開(在默認皮膚):

// ==UserScript== 
// @name   New Tab in phpBB3 
// @namespace  http://robert.walkertribe.com/ 
// @description Makes links in posts in phpBB3 boards open new tabs. 
// ==/UserScript== 

var newWin = function(ev) { 
    var win = window.open(ev.target.href); 
    if (win) ev.preventDefault(); 
}; 

var links = document.evaluate(
     "//div[@class='content']//a[not(@onclick) and not(@href='#')]", 
     document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); 

for (var i = 0; i < links.snapshotLength; i++) { 
    var link = links.snapshotItem(i); 
    link.addEventListener("click", newWin, true); 
} 

代碼中使用XPath表達式識別所有a要素:1)做沒有onclick屬性,2)其href屬性未設置爲"#",以及3)在div的內部找到,其class屬性設置爲"content"

+1

我想評論說,儘管人們普遍擔心XPath可能會比DOM行走的代價太昂貴,但我發現它即使在積極使用時也能立即執行。 – 2008-09-23 15:20:48

10

腳本可以添加圖形到一個頁面,即使你沒有任何地方託管文件,通過數據URI。

例如,這裏是一個小按鈕圖形:

 
var button = document.createElement("img"); 
button.src = "data:image/gif;base64," 
    + "R0lGODlhEAAQAKEDAAAA/wAAAMzMzP///yH5BAEAAAMALAAAAAAQABAAAAIhnI+pywOtwINHTmpvy3rx" 
    + "nnABlAUCKZkYoGItJZzUTCMFACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw==" 
somenode.appendChild(button); 

這是一個在線image encoder

wikipedia article關於數據URI標準。

2

一個有用的XPath技術是指定您的匹配相對於您已經找到的節點。至於計算器一個人爲的例子:

 
// first we got the username link at the top of the page 
var hdrdiv = document.evaluate(
    "//div[@id='headerlinks']/a[1]", document, null, 
    XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; 

// now we can retrieve text that follows it, (user's reputation score) 
// (note that hdrdiv is now the contextNode argument, rather than document) 
var reptext = document.evaluate(
    "following-sibling::span", hdrdiv, null, 
    XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; 

alert("Reputation Score: " + reptext.textContent); 

可以匹配任何相對於contextNode方向,祖先,子孫,以前,以下。 這是一個有幫助的 XPath reference

2

GreaseMonkey腳本在DOM準備就緒時運行,因此您不需要添加onload事件,只需在GreaseMonkey腳本中直接操作DOM即可。

13
==UserScript== 
... 
@require http://ajax.googleapis.com/ajax/framework-of-your/choice.js 
==/UserScript== 
5

GM_setValue通常僅存儲32位整數,字符串和布爾值,但是可以利用uneval()方法(和在檢索後的eval())來存儲任何對象。如果您正在處理純JSON值(而不是JavaScript對象),請使用JSON.stringify存儲並使用JSON.parse進行檢索;這將會更快更安全。

var foo={people:['Bob','George','Smith','Grognak the Destroyer'],pie:true}; 
GM_setValue('myVeryOwnFoo',uneval(foo)); 
var fooReborn=eval(GM_getValue('myVeryOwnFoo','new Object()')); 
GM_log('People: '+fooReborn.people+' Pie:'+fooReborn.pie); 

我傾向於使用「新的對象()」作爲我在這種情況下默認,但你也可以使用「{}」。請記住,「{}」評估爲字符串,而不是對象。像往常一樣,小心()。

1

已過時: Firefox在Greasemonkey腳本中用FF版本17取消了對E4X的支持。使用GM_info來獲取元數據。


您可以使用E4X訪問您的== == UserScript信息作爲變量:

var metadata=<> 
// ==UserScript== 
// @name   search greasemonkey 
// @namespace  foo 
// @include  http://*.google.com/* 
// @include  http://*.google.ca/* 
// @include  http://search.*.com/* 
// @include  http://*.yahoo.com/* 
// ==/UserScript== 
</>.toString();