Background script messaging with javascript - javascript

I was messing around with communicating inside a Google Chrome extension and was using the following guide: https://developer.chrome.com/extensions/messaging
It used to work but I have encountered an error :
Error in response to tabs.query: TypeError: Cannot read property 'id'
of undefined
I compared my code and the Google Chrome code and I can't seem to find why my code produces that error:
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[1].id, {fen: request.needMove}, function(response) {
//console.log(response.farewell);
});
});
Here is where I send it to:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log("recv FEN : " + FEN);
FEN = request.fen;
setCookie("FEN_SET", "true" , 1);
setFEN(FEN);
});
I can't fix that error, whatever I try it stays the same.
"Cannot read property of undefined" is implying that 'tabs' is undefined as far as I understood but I don't understand why it works in the Google example and here it doesn't.
Another Q :
If I'm trying to send it to tabs[1] does that mean it's the tab in the second position, or am I interpreting it wrong?

tabs is the list of all tabs (regardless of position) that pass the filter.
Your query is {active: true, currentWindow: true}, so normally it should be just 1 tab (as there is at most 1 current window with exactly 1 active tab).
So you need the first element, which is tabs[0].
tabs[1] will always be undefined with this query.
Cases when tabs will be empty empty used to be exceedingly rare (Chrome running in background with no windows open).
However, with a recent change the API will not return the Dev Tools tab. So if you're debugging your extension and the Dev Tools window is open and focused, the array will be empty. You should check for that.

Related

What does tabs[0] mean in browser extensions?

In the Firefox example of browser extensions, the popup script sends a message to the content script using the following:
browser.tabs.sendMessage(tabs[0].id, {
command: "beastify", beastURL: url }
Looking through the MDN documentation doesn't give a clear cut answer as to what tabs really is. It seems like its an array containing all the tab objects in the browser. But how do I know what tabs[0] is? and what about the rest of the array?
Is using tabs[0] equivalent to finding the current active tab?
This is from Firefox documentation
browser.tabs
.query({ active: true, currentWindow: true })
.then(beastify)
....
function beastify(tabs) {
browser.tabs.insertCSS({ code: hidePage }).then(() => {
let url = beastNameToURL(e.target.textContent);
browser.tabs.sendMessage(tabs[0].id, {
command: "beastify",
beastURL: url
});
});
}
As you can see the beastify function is called with list (array) of tabs from browser.tabs.query()
Because only one tab in the same window can be active, it's save to say that the list will contain only single item, hens we can safely use tabs[0] to access first and only item in the array.

What is the equivalent command to close for chrome.runtime.openOptionsPage?

In a Chrome extension what is the equivalent of close to chrome.runtime.openOptionsPage? I have tried:
window.close();
and
chrome.runtime.closeOptionsPage();
This would need to be invoked from within the options page itself.
Update
According to wOxxOm in the comments below, "window.close()" should work. So this may be a bug in my browser Edge.
wOxxOm suggested using "chrome.tabs.remove". However I get an error using it this way from within the options script:
chrome.tabs.getCurrent(function(tab) {
chrome.tabs.remove(tab.id, function() { });
});
Error handling response: TypeError: Cannot read property 'id' of undefined

Why does my script for a Chrome extension that is meant to get the current url not work?

I got a script from Stack Overflow for getting the current Chrome tab, but every time I try to run it, this error shows up in Google Chrome:
Uncaught TypeError: Cannot read property 'query' of undefined
Context
https://www.youtube.com/
Stack Trace
**chrome.tabs.query({active: true, currentWindow: true}, tabs => {**
let url = tabs[0].url;
// use `url` here inside the callback because it's asynchronous!
});
The code in bold is the highlighted code in the error. I have tried to replace currentWindow with lastFocusedWindow, but that did nothing. The permissions are all correct, and I even added extra permissions that I do not need, as shown here:
"permissions": [
"tabs",
"<all_urls>",
"activeTab" ]
I only need tabs and <all_urls> for my script, but I have activeTab just in case. What is the problem here, and how can I fix it?
There are two ways to do it.
calling getCurrent(). More details here on which page you should execute the script -> https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/getCurrent
chrome.tabs.getCurrent(function callback)
If you want the current URL on click of browser action then.
chrome.browserAction.onClicked.addListener( activeTab => {
console.log(activeTab);
});

Getting active tab information using chrome extension api

I am working on a chrome extension, and I need information about the active tab (when I say "active", I mean the tab that I am looking at in the current window that is focused).
Using the chrome.tabs api, I should be able to do something like the following to get what I want:
function getActiveTab() {
var activeTabInfo = {"currentWindow": true, "active" : true};
return chrome.tabs.query(activeTabInfo,function (tabs) {
return tabs[0];
});
}
However, when I log the length of tabs within the callback, I'm getting a length of 0. I modeled this snippet after How to fetch URL of current Tab in my chrome extension using javascript, but can't seem to get it to work.
Any thoughts?

Same Domain not loading in IE iFrame if devtools aren't up [duplicate]

IE9 Bug - JavaScript only works after opening developer tools once.
Our site offers free pdf downloads to users, and it has a simple "enter password to download" function. However, it doesn't work at all in Internet Explorer.
You can see for yourself in this example.
The download pass is "makeuseof". In any other browser, it works fine. In IE, both buttons do nothing.
The most curious thing I've found is that if you open and close the developer toolbar with F12, it all suddenly starts to work.
We've tried compatibility mode and such, nothing makes a difference.
How do I make this work in Internet Explorer?
It sounds like you might have some debugging code in your javascript.
The experience you're describing is typical of code which contain console.log() or any of the other console functionality.
The console object is only activated when the Dev Toolbar is opened. Prior to that, calling the console object will result in it being reported as undefined. After the toolbar has been opened, the console will exist (even if the toolbar is subsequently closed), so your console calls will then work.
There are a few solutions to this:
The most obvious one is to go through your code removing references to console. You shouldn't be leaving stuff like that in production code anyway.
If you want to keep the console references, you could wrap them in an if() statement, or some other conditional which checks whether the console object exists before trying to call it.
HTML5 Boilerplate has a nice pre-made code for console problems fixing:
// Avoid `console` errors in browsers that lack a console.
(function() {
var method;
var noop = function () {};
var methods = [
'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
'timeStamp', 'trace', 'warn'
];
var length = methods.length;
var console = (window.console = window.console || {});
while (length--) {
method = methods[length];
// Only stub undefined methods.
if (!console[method]) {
console[method] = noop;
}
}
}());
As #plus- pointed in comments, latest version is available on their GitHub page
Here's another possible reason besides the console.log issue (at least in IE11):
When the console is not open, IE does pretty aggressive caching, so make sure that any $.ajax calls or XMLHttpRequest calls have caching set to false.
For example:
$.ajax({cache: false, ...})
When the developer console is open, caching is less aggressive. Seems to be a bug (or maybe a feature?)
This solved my problem after I made a minor change to it. I added the following in my html page in order to fix the IE9 problem:
<script type="text/javascript">
// IE9 fix
if(!window.console) {
var console = {
log : function(){},
warn : function(){},
error : function(){},
time : function(){},
timeEnd : function(){}
}
}
</script>
Besides the 'console' usage issue mentioned in accepted answer and others,there is at least another reason why sometimes pages in Internet Explorer work only with the developer tools activated.
When Developer Tools is enabled, IE doesn't really uses its HTTP cache (at least by default in IE 11) like it does in normal mode.
It means if your site or page has a caching problem (if it caches more than it should for example - that was my case), you will not see that problem in F12 mode. So if the javascript does some cached AJAX requests, they may not work as expected in normal mode, and work fine in F12 mode.
I guess this could help, adding this before any tag of javascript:
try{
console
}catch(e){
console={}; console.log = function(){};
}
If you are using AngularJS version 1.X you could use the $log service instead of using console.log directly.
Simple service for logging. Default implementation safely writes the message into the browser's console (if present).
https://docs.angularjs.org/api/ng/service/$log
So if you have something similar to
angular.module('logExample', [])
.controller('LogController', ['$scope', function($scope) {
console.log('Hello World!');
}]);
you can replace it with
angular.module('logExample', [])
.controller('LogController', ['$scope', '$log', function($scope, $log) {
$log.log('Hello World!');
}]);
Angular 2+ does not have any built-in log service.
If you are using angular and ie 9, 10 or edge use :
myModule.config(['$httpProvider', function($httpProvider) {
//initialize get if not there
if (!$httpProvider.defaults.headers.get) {
$httpProvider.defaults.headers.get = {};
}
// Answer edited to include suggestions from comments
// because previous version of code introduced browser-related errors
//disable IE ajax request caching
$httpProvider.defaults.headers.get['If-Modified-Since'] = 'Mon, 26 Jul 1997 05:00:00 GMT';
// extra
$httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache';
$httpProvider.defaults.headers.get['Pragma'] = 'no-cache';
}]);
To completely disable cache.
It happened in IE 11 for me. And I was calling the jquery .load function.
So I did it the old fashion way and put something in the url to disable cacheing.
$("#divToReplaceHtml").load('#Url.Action("Action", "Controller")/' + #Model.ID + "?nocache=" + new Date().getTime());
I got yet another alternative for the solutions offered by runeks and todotresde that also avoids the pitfalls discussed in the comments to Spudley's answer:
try {
console.log(message);
} catch (e) {
}
It's a bit scruffy but on the other hand it's concise and covers all the logging methods covered in runeks' answer and it has the huge advantage that you can open the console window of IE at any time and the logs come flowing in.
We ran into this problem on IE 11 on Windows 7 and Windows 10. We discovered what exactly the problem was by turning on debugging capabilities for IE (IE > Internet Options > Advanced tab > Browsing > Uncheck Disable script debugging (Internet Explorer)). This feature is typically checked on within our environment by the domain admins.
The problem was because we were using the console.debug(...) method within our JavaScript code. The assumption made by the developer (me) was I did not want anything written if the client Developer Tools console was not explicitly open. While Chrome and Firefox seemed to agree with this strategy, IE 11 did not like it one bit. By changing all the console.debug(...) statements to console.log(...) statements, we were able to continue to log additional information in the client console and view it when it was open, but otherwise keep it hidden from the typical user.
I put the resolution and fix for my issue . Looks like AJAX request that I put inside my JavaScript was not processing because my page was having some cache problem. if your site or page has a caching problem you will not see that problem in developers/F12 mode. my cached JavaScript AJAX requests it may not work as expected and cause the execution to break which F12 has no problem at all.
So just added new parameter to make cache false.
$.ajax({
cache: false,
});
Looks like IE specifically needs this to be false so that the AJAX and javascript activity run well.

Categories

Resources