2

I am writing a chrome extension which should change the content-type of http responses. It is working fine. Now, I want to control it using keypress i.e. user should be able to bypass the default action of extension on keypress. I tried this, but it doesn't work:

background.js

var enableEXT = true;
window.onkeydown = function() 
{
    console.log('Testing hello');
    if (event.keyCode == 70)
        enableEXT = false;
    console.log(event.keyCode);
    console.log(enableEXT);
};
window.onkeyup = function() 
{
    enableEXT = true;
    console.log(event.keyCode);
};
chrome.webRequest.onHeadersReceived.addListener(function(details) {
for (var i = 0; i < details.responseHeaders.length; ++i) 
{
    if (details.responseHeaders[i].name.toLowerCase() == 'content-type' && !enableEXT)
        details.responseHeaders[i].value = 'application/xyz';
}
return {responseHeaders: details.responseHeaders};
}, {urls: ["<all_urls>"]}, ['blocking', 'responseHeaders']);
adnan kamili
  • 8,967
  • 7
  • 65
  • 125
  • This worked for me http://stackoverflow.com/questions/10396034/how-can-i-communicate-between-background-js-and-popup-js – adnan kamili Sep 07 '13 at 21:46

2 Answers2

3

Try using a content script, injected into the web page, instead of a background script. Use this in your manifest.json:

"content_scripts" : [{
    "js" : ["myScript.js"]
}]


"permissions": [
    "tabs", "http://*/*", "https://*/*"
]

However, chrome extensions are sandboxed from other scripts in the page. However, you do have access to the DOM and you can inject your own tags. So, create a new <script> tag and append it to the DOM, and the new script (script.js) it references can include the event listeners you want.

background.js:

chrome.runtime.onConnect.addListener(function(port) {
  port.onMessage.addListener(function(msg) {
    enableEXT = msg.enableEXT;
  });
});

chrome.webRequest.onHeadersReceived.addListener(function(details) {
for (var i = 0; i < details.responseHeaders.length; ++i) 
{
    if (details.responseHeaders[i].name.toLowerCase() == 'content-type' && !enableEXT)
        details.responseHeaders[i].value = 'application/xyz';
}
return {responseHeaders: details.responseHeaders};
}, {urls: ["<all_urls>"]}, ['blocking', 'responseHeaders']);

myScript.js:

//to inject into the page
var s = document.createElement('script');
s.src = chrome.extension.getURL("script.js");
s.onload = function() {
    this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(s);

//to communicate with our background
var port = chrome.runtime.connect();

window.addEventListener("message", function(event) {
    // We only accept messages from ourselves
    if (event.source != window)
      return;

    if (event.data.type && (event.data.type == "FROM_PAGE")) {
      port.postMessage(event.data);
    }
}, false);

script.js:

window.onkeydown = function() 
{
    if (event.keyCode == 70)
        window.postMessage({ enableEXT: true, "*");
};
window.onkeyup = function() 
{
    window.postMessage({ enableEXT: false, "*");
};

To communicate between your injected code, your content script, and your background page is a very awkward situation, but can be dealt with, with all the postMessage APIs...

mdenton8
  • 619
  • 5
  • 13
  • now keycode is working but headers are not getting modified, should I put header modification part in background.js, in that case how can I access enableEXT variable – adnan kamili Sep 07 '13 at 20:11
  • Let me think about that for a little bit. Btw, I've been looking for a chrome extension to modify responses for a while now... Feel like extending the functionality of your extension? :) – mdenton8 Sep 07 '13 at 20:17
  • I kept the header modification part in background.js and it is working, but now I don't have any access to enableEXT variable. Again got stuck – adnan kamili Sep 07 '13 at 20:20
  • And then communicate from your content script to your background with chrome.runtime.sendMessage()... – mdenton8 Sep 07 '13 at 20:26
  • I will be waiting, Thanks – adnan kamili Sep 07 '13 at 20:31
  • Okay, I finished. The postMessage things might work, they might not. They may need to be passed as strings with JSON.stringify and JSON.parse, not completely sure. – mdenton8 Sep 07 '13 at 20:40
  • where to mention script.js in manifest.json, script.js is denied loading – adnan kamili Sep 07 '13 at 20:51
  • perhaps add the permissions i specified in the answer at the top – mdenton8 Sep 07 '13 at 20:58
  • There was a much simpler way http://stackoverflow.com/questions/10396034/how-can-i-communicate-between-background-js-and-popup-js – adnan kamili Sep 07 '13 at 21:46
  • That method was more or less exactly what I used – mdenton8 Sep 07 '13 at 22:34
  • I want to do the same thing, have keyboard shortcuts that work on a web page. chrome.extension.getURL("script.js") is [deprecated](https://developer.chrome.com/extensions/extension#method-getURL), and both it and its replacement, [chrome.runtime.getURL](https://developer.chrome.com/extensions/runtime#method-getURL), fail as invalid URLs when used this way, resolving to chrome-extension://invalid/. Is there any way to load an extension script directly into a page via its URL? Copying the js out of it and adding as the text of the script element works, but I'd much rather use a working URL. – enigment Apr 02 '19 at 20:34
0

Add a parameter named event to the event handlers you assign to the events like this:

window.onkeydown = function(event) 
{
    console.log(event.keyCode);
};
sudee
  • 773
  • 9
  • 14