2

我正在做一個與Chrome聊天交互的Google Chrome擴展,並且可以將相同的消息發送給所有打開的聊天,功能部分已完成,但我無法將​​事件發送給文字區域。Google Chrome擴展中的Fire Keydown事件

我在做什麼是使用page_action來顯示用戶訪問Gmail時的擴展名圖標。當用戶點擊擴展圖標時,它會提示一個帶有textarea的彈出窗口,當用戶打開聊天並向textarea寫入內容,然後按輸入鍵時,每個打開的聊天的textarea將填充相同的消息並被認爲是觸發​​事件。

這裏是esencial代碼:

popup.js

chrome.tabs.executeScript(null, {file: 'send.js'}, function() { 
    // 'message' is the textarea inside the popup.html 
    var message = document.getElementById('message'); 

    message.onkeydown = function (e) { 
    if (13 == e.keyCode) { 
     chrome.tabs.executeScript(null, {code: 'send("' + message.value + '");'}, function() { 
     message.value = ''; 
     }); 
     return false; 
    } 
    }; 
}); 

send.js

function send(message) { 
    if (message) { 
    for (var i = 0, textareas = document.getElementsByTagName("TEXTAREA"), length = textareas.length; i < length; ++i) { 
     textarea = textareas[i]; 
     textarea.value = message; 

     var evt = document.createEvent('KeyboardEvent'); 

     evt.initKeyboardEvent('keydown', true, true, null, false, false, false, false, 13, 13); 

     Object.defineProperty(evt, 'keyCode', { 
     get : function() { 
      return 13; 
     } 
     }); 

     Object.defineProperty(evt, 'which', { 
     get : function() { 
      return 13; 
     } 
     }); 

     Object.defineProperty(evt, 'keyIdentifier', { 
     get : function() { 
      return 'Enter'; 
     } 
     }); 

     Object.defineProperty(evt, 'shiftKey', { 
     get : function() { 
      return false; 
     } 
     }); 

     textarea.dispatchEvent(evt); 
    } 
    } 
} 

的代碼沒有問題填滿文字區域,因此所有textareas被重新調整,但​​事件沒有在腳註後觸發t填充textareas。奇怪的部分是,當我嘗試將send.js代碼放入Google Chrome控制檯時,​​事件正常啓動並且發送了消息,但我無法對該擴展程序做同樣的事情。

那麼,如何將​​事件放入擴展中?

+0

您能否提供js小提琴演示 – shareef

+0

您是否在擴展中或僅在網頁中使用Chrome Inspector? –

+0

@NathanCampos我使用開發工具來檢查彈出窗口和網頁。 –

回答

1

Gmail由框架組成。
默認情況下,chrome.tabs.executeScript只在主(頂窗口)框架中注入代碼。要在子幀中注入代碼,請將allFrames: true添加到您的詳細信息中。

另外,做不是使用'send("' + USER_INPUT_HERE + '");'觸發您的功能。這使得您的應用程序易受腳本注入的影響。使用JSON.stringify(USER_INPUT_HERE)正確地轉義字符串。漏洞的

chrome.tabs.executeScript(null, { 
    file: 'send.js', 
    allFrames: true 
}, function() { 
    chrome.tabs.executeScript(null, { 
     code: 'send(' + JSON.stringify(message.value) + ');', 
     allFrames: true 
    }); 
    message.value = ''; 
}); 

示例:
用戶輸入:由延伸創建" + (function(){while(1)chrome.tabs.create({url:"http://evil.com"})}()) + "


對象從未傳遞到頁。添加到事件的屬性和屬性描述符在傳遞到頁面時會丟失。取而代之的是內容腳本,我建議使用一個injected scriptWhat is the difference between an injected script, Content script and extension code?取得預期的效果:

// Script to be injected 
var code = '(' + function(message) { 
    /* .. "function send"'s body from send.js .. */ 
} + ')(' + JSON.stringify(message.value) + ');'; 
// Content script which *injects* the script 
chrome.tabs.executeScript(null, { 
    code: 'var s = document.createElement("script");' + 
      's.textContent = ' + JSON.stringify(code) + ';' + 
      '(document.head||document.documentElement).appendChild(s);' + 
      's.parentNode.removeChild(s);' /*<--Clean-up*/ 
}); 

爲了清楚起見,在下面的代碼上面的代碼片段的結果是在頁面injected

(function(message) { /* logic of send */ })("user input"); 

Event對象在Gmail的頁面中構造並傳遞,以便保留所有屬性,就像您使用控制檯執行腳本一樣。它不會在您的分機上下文中運行

+0

感謝您指出此漏洞。我知道Gmail由框架組成,但Gmail中的聊天不在框架中,因此不是問題所在。我沒有修改textareas的值的問題,所以問題不在於腳本無法找到textarea,問題是腳本不能正確激發'keydown'事件。 –

+0

@ Fong-WanChau編輯答案,目標*另一個*問題。 –

+0

但是,對象是在注入頁​​面的'send.js'內部創建的,因此從技術上講該對象是在頁面內部創建的。我使用了'console.log(evt)',在頁面檢查器中,我可以看到'evt'被正確創建。 –