chrome插件訪問原始頁面的變量


開發chrome插件時遇到需要獲取原始網頁中的一個js變量的值問題。由於content.js和原始網頁的作用域環境不同,無法直接獲取變量的值,提示undefined。谷歌找到大神提供的辦法。綜合起來記錄如下:

考慮到Google Reader的網頁太復雜,這里就以Google首頁來舉例了。打開網頁后,右鍵打開審查元素,然后在控制台輸入fp,就會看到一個字符串,這就是原始網頁的一個全局變量。

現在我要獲取它,就可以創建一個script元素,append到head。而這個script元素的執行環境是原始網頁的,可以自由使用fp這個變量。
不過fp取出來后也沒法直接傳遞回content script。好在文檔里說DOM是共用的,所以可以在這個script里,把值設置為某個元素的屬性或innerText,再在content script里獲取就行了:

setTimeout(function() {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.innerHTML = "document.body.setAttribute('data-fp', fp);";
    document.head.appendChild(script);
    document.head.removeChild(script);

    console.log(document.body.getAttribute('data-fp'));
}, 1000);

 

這里延遲的原因是原始網頁加載完時,還需要等一會才會創建fp變量。

另一種辦法就是使用location.href,它是用來跳轉網頁的,但是也可以用來執行JavaScript,並且執行環境也是原始網頁:

setTimeout(function() {
    location.href = "javascript:document.body.setAttribute('data-fp', fp);";
    setTimeout(function() {
        console.log(document.body.getAttribute('data-fp'));
    }, 0);
}, 1000);

 

這里嵌套使用了setTimeout,原因是跳轉是一個事件,並不會打斷當前腳本的執行(而添加script元素會立刻執行),因此需要讓后面的語句等待事件處理完畢。

不過前面所說的方法都必須先保存,再取出,能這樣做的只有字符串等簡單類型,對函數則無能為力了。
實際上還有更方便的方法,那就是在DOM上綁定一個事件,而事件的處理函數則返回window變量,再在程序中觸發這個事件,就能獲得執行環境的window變量了。幸運的是,這個執行環境仍然是原始網頁的:

setTimeout(function() {
    var div = document.createElement('div');
    div.setAttribute('onclick', 'return window;');
    var unsafeWindow = div.onclick();
    console.log(unsafeWindow.fp);
}, 1000);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM