BroadcastChannel.onmessage not working in firefox - javascript

I need to share some information between 2 tabs of the same browser pointing at the same site. I'm using the BroadcastChannel.onmessage event handler as detailed here:
https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel/onmessage
In the sender tab javascript code I defined:
var bc = new BroadcastChannel('my_bc_channel');
bc.postMessage(i); //where i is simply the line number i want to share
And in the receiving tab:
var bc = new BroadcastChannel('my_bc_channel');
//then use this to receive the incoming messages:
bc.onmessage = function (ev) {
last_line = ev.data
}
My code works fine in Chrome, but it does not do anything in Firefox (latest version 70 freshly installed under windows). The compatibility chart in the link I gave above says it should be working from Firefox version 38.
The thing is, I'm not sure how to debug this. I don't have any error messages in the console. I don't know if it's the sender code that does not send anything. But clearly the receiving code is not triggered so I guess the .onmessage event is not detected. Where can I see in the javascript console if the message is sent ?

I opened a bug report:
https://bugzilla.mozilla.org/show_bug.cgi?id=1600512
Seems BroadcastChannel.onmessage does not work properly when you host your files locally on your hard drive, as I did in my example above. It works otherwise.

It might be that the channel "in the receiving tab" has it's onmessage handler set only after the other tab has broadcast the message, and the message is lost.
You might want the "sending" tab to also set a message handler, and wait for the other tab to broadcast a message that it is ready to receive, and only then start the broadcast.

Related

Send a message from Dialog box (mean-stack site) to the task pane

I am trying to use Dialog API of Office addin.
I can successfully open a Dialog box from my task pane by:
$scope.openDialog = function () {
Office.context.ui.displayDialogAsync('https://localhost:3000/home',
function (asyncResult) {
dialog = asyncResult.value;
dialog.addEventHandler(Office.EventType.DialogMessageReceived, processMessage);
});
}
My Dialog box is a mean-stack site. I have added <script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script> in the index.html. And I tried to use Office.context.ui.messageParent(true);, it shows an error in console:
And I see in the doc that I don't understand quite well:
The Office JavaScript library is loaded in the page. (Like any page
that uses the Office JavaScript library, script for the page must
assign a method to the Office.initialize property, although it can be
an empty method. For details, see Initializing your add-in.)
I also tried to add Office.initialize = function () { }; in index.html, the error is still there, and processMessage of the task pane does not seem to receive anything.
So is there anything special I should do to my mean-stack site so that it could use messagePerent?
The console error will not introduce any bad effect to the dialog. We already fixed it internal. You can just ignore this error. Did you check whether office.context.ui.messageParent is null or undefined ? if it is not, then the dialog has been initialized successfully. Then it will be only something wrong with the postMessage method, what system and browser version are you using ?
1. If it is Win10 and latest version of IE, please make sure the dialog first page domain is same with the taskpane domain. Or you can use other browser to try it.
2. If it is Win7&8&8.1 and IE, then you can just try in other browser to see whether the messageParent api is work. We have already done a code change to fix the IE issue. It will be deployed to prod soon.

Inconsistent execution of executeScript in Cordova inAppBrowser on iOS

I'm having some trouble with some inAppBrowser behavior in my cordova app. Here's the code:
var codePass = fooCode;
var executeScriptFunc = function(event) {
ref.executeScript({
code: codePass
}, function (value) {});
ref.removeEventListener('loadstop', executeScriptFunc);
};
var ref = cordova.InAppBrowser.open(fooObject.link, "_blank", "location=yes,enableViewportScale=yes");
ref.addEventListener('loadstop', executeScriptFunc)
The strange thing here is that the code works perfectly every time when emulated. It opens the browser and executes the script no problem. But when I try it on my actual iPhone device, it doesn't always work. The script executes maybe every other time. But it's never even that consistent.
Both the emulator and iPhone are using iOS 9.3.4. Any ideas?
If the site inside the inAppBrowser happens to be served via HTTPS, the callback for executeScript() will not work if the site employs a Content-Security-Policy HTTP response header that does not contain the gap: or gap-iab: schemes for the default-src directive. These are needed because execution of the callback function on iOS relies on an iframe that gets added to the page.
You can check whether this is the root cause for the problem by opening Safari’s Web Inspector for the inAppBrowser—it has a separate Web Inspector instance, independent of the parent application that opened it—and look out for a corresponding error message in the console. Note that you should open the console before executeScript() is run, or otherwise you might not get the error message.
Make sure also that you don't have other event handlers firing at the same time during your polling.
I had multiple pollers all firing every second and that's when I ran into the issue.
After changing the polling time so they all fired at different times, the issue went away.

Firefox Javascript console and network tab not showing important errors?

While casually debugging some javascript on a web page, I noticed that Firefox (33.0 - Windows 7) Javascript console would not tell me if some .js files failed to load, so I decided to give this a closer look.
What I found is that if I have an HTML with a script tag pointing to a wrong local url, as the page loads the console shows no errors at all. Instead it shows the full path and file name for the wrong .js script as if there was nothing wrong with it.
I also tried with a button element issuing a xmlhttprequest to a non existing remote url, and same thing, no errors at all in the console when clicking.
$("#button").click(function(){
console.log("clicked me")
$.getJSON("demo_ajax_json.js",function(result){
$.each(result, function(i, field){
$("div").append(field + " ");
});
});
});
while "clicked me" will show as expected.
Also I verified that every possible log setting in developer tools is checked.
After reading that someone had luck with complete settings reset I went through that using Menu > Help > Troubleshooting > Reset Firefox settings. But... no. The errors still don't show up.
So, end of the story, given I just recently decided to look into this, and I can't exactly remember how long I've not been seeing errors exactly, I am questioning myself whether those kind of errors do not shown up at all in Firefox by design and if it's just a prerogative of Chrome... which, it goes by itself, shows all the errors (like for example "net::ERR_FILE_NOT_FOUND").
Anyone for a quick test on their console?
UPDATE, attaching screenshots of both Firefox and Chrome.
As you can see the situation is totally different.
Code:
Firefox Console Tab:
Also no errors on the missing files, whose name is just printed out normally in the console as if nothing was wrong with them.
Firefox Network Tab:
AS OPPOSED TO
Chrome Console Tab:
Chrome Network Tab:
After looking at the screenshots you added, I noticed that you were references resources on your local file system, so I decided to do some tests. I found that Firefox indeed does not report network errors for files on the local filesystem, reporting nothing on the console or the network tab, however it does report them properly for network resources. Unfortunately I could not reproduce the errors in chrome exactly, as my local filesystem is locked down rather tightly (I'm on an enterprise-owned system) and chrome simply reports that it doesn't have permission to access the local filesystem, regardless of whether the file exists or not (Firefox says nothing). Meanwhile, I imagine if you pointed your script/link tags to a network address such as a CDN, or if you are testing on a local test server something like:
http://localhost/[script-address]
it should report the error in both consoles.
Here's my test code:
And the firefox net panel
And the chrome console
Preserving my original answer below this point, as the JQuery API notes may be helpful for others who find themselves here
As mentioned in Ian's comment, and the JQuery API document at http://api.jquery.com/jQuery.getJSON/ JQuery's getJSON method will simply fail silently if you have a syntax error, the URL doesn't exist, or if it doesn't return a response. You can force it to do so by adding a .fail() method call to the end like so:
$("#button").click(function(){
console.log("clicked me")
$.getJSON("demo_ajax_json.js",function(result){
$.each(result, function(i, field){
$("div").append(field + " ");
});
}).fail(function() {
console.log("AJAX request failed");
});
});
You can also bind a function to the error event by using the .ajaxError method documented here: http://api.jquery.com/ajaxError/
$.ajaxError(function() {
console.log("AJAX request failed.");
});
Note that when you do it this way, JQuery will pass the function several useful parameters if you create variables to hold them, including the error event itself, the ajax object that triggered it, the settings that were used, and the error string, which you can then use to output whatever information you need to the console in order to debug what was causing your error. Good luck!

Javascript running only once on Internet Explorer, runs properly when developer tools is open

We have an unusual problem with javascript running on IE 11. I tried it on one of our servers running IE8 and the same problem occurs. However, it runs fine on Chrome and Mozilla.
Here's the code in question:
SetGuideFatningCookie(fid); //set a cookie according to user choice
var validFatningCombo = ValidFatningCheck(); //ask server if user choice is valid using XMLHttpRequest GET request
if(validFatningCombo)
window.location.href = GetGuideTilbehoerURL(); //if valid redirect user to next page
else
popAutoSizeFancy("#GLfancy"); //if not show a fancybox with error text
The user chooses one of 7 choices. Then they click a button that runs the above code. The code sets a cookie containing the user's choice and asks the server if the choice is valid. If valid - we redirect the user and if not, we open a fancybox that contains some error text and two buttons - "Try again"(closes box and they can try again) and "Send us a message"(redirects user to our "ask us a question" page).
The code runs fine the first time the user goes to this process.
However, if they have chosen an invalid choice, they close the fancybox and try to choose another choice and continue -> then the fancy box appears ALWAYS, regardless of what the user chooses.
If they choose a valid choice and continue, get redirected to next page, then come back to this page and choose an invalid choice and press continue -> then they can continue to the next page without fancybox ever coming up.
However, if IE's developer tools are opened, the code runs correct every single time.
I have found many threads describing this is a problem with console.log. I have removed every single reference to console.log from all our .js files. It could be one of the external libraries that we are using, like jquery, modernizr, fancybox and menucool's tooltip library.
Therefore I tried including a console fallback function for IE, like this thread suggests:
Why does JavaScript only work after opening developer tools in IE once?
I am currently trying with this one, and I have tried every single other fallback console replacement from the thred I link to.
if (!window.console) window.console = {};
if (!window.console.log) window.console.log = function () { };
I tried including it:
Somewhere in our .js files
script element in head after loading all our .js files and all external libraries
script element in head before loading all our .js files and all external libraries
Inside $(document).ready(function() {}); , in a script element in head after loading all other js
So far, none of the fallback pieces of code I have tried in any of these 4 locations have solved the problem. It always behaves the same way in IE. I couldn't find another explanation than the "console" one for this problem so far, so if anyone got any insight on it, it would be greatly appreciated.
EDIT: I will include some more info:
The very act of opening Developer Tools removes the unwanted behaviour. No errors are ever shown in console.
I checked the server side to see if the server is getting the call from ValidFatningCheck(); It turns out that the call is made only the first time (or if Developer tools is open - every time) which is rather mysterious since the redirect/fancybox line comes after the server call and it doesn't fail to run, even if it runs wrong.
function ValidFatningCheck(){
var requestUrl = '/Tools.ashx?command=validscreen';
var req = new XMLHttpRequest();
req.open('GET', requestUrl, false);
req.send(null);
var res = "";
if (req.readyState==4)
res = req.responseText;
if(res == "true")
return true;
return false;
}
UPDATE : Problem solved by adding a timestamp to my XMLHttpRequest as multiple replies suggested. I didn't realize XMLHttpRequest uses AJAX so I overlooked it as a probable cause to the problem.
(I put in comments but will make this an answer now as it appears to have solved the problem) get requests are cached by IE but when the developer console is open it does not perform this cache.
three ways to fix:
add a timestamp to the request to trick the browser into thinking it is making a new request each time
var requestUrl = '/Tools.ashx?command=validscreen&time='+new Date().getTime();
set the response header to no-cache
make a POST request as these are not cached
(as pointed out by #juanmendes not ideal you are not editing a resource)

Event onBrowserClose for Google Chrome Extension?

I am developing an extension for Google Chrome. My background script, everytime, authorizes on a server that uses the XMPP API, and subscribes for a PubSub node. I need to unsubscribe on the exit, otherwise the dummy subscriptions will remain on the server. Is There any onBrowserClose event in the Google Chrome Extension APIs?
There is no such event in the Chrome Extension API.
There is however a chrome.windows.onRemoved event that fires each time a window closes. I figured you could check in this event if you closed the last window, but unfortunately due to the asynchronous nature of Chrome this doesn't work.
What I tried was running a simple AJAX request in the onRemoved event handler. The AJAX request never got to the server, as Chrome had already closed before running the event (or just disregarded it).
Making the final answer be: No, currently you can't, as far as I know. You might want to star the following bug report at http://crbug.com/30885 to get noticed on updates.
If you catch the case when the number of open tabs is 0, you can treat that as a Chrome onClose event. In my case, I have to cancel a desktop notification before Chrome closes because it was crashing otherwise.
This is how I did it:
1. Initialize a variable num_tabs by using the following:
chrome.tabs.getAllInWindow( null, function( tabs ){
console.log("Initial tab count: " + tabs.length);
num_tabs = tabs.length;
});
2. Increment num_tabs when a tab is created:
chrome.tabs.onCreated.addListener(function(tab){
num_tabs++;
console.log("Tab created event caught. Open tabs #: " + num_tabs);
});
3. Decrement num_tabs when a tab is removed and run your browser onclose event handler if num_tabs = 0
chrome.tabs.onRemoved.addListener(function(tabId){
num_tabs--;
console.log("Tab removed event caught. Open tabs #: " + num_tabs);
if( num_tabs == 0 )
notification.cancel();
});
Adding a browser close event is a pretty frequent request. Star http://crbug.com/30885 for updates. And read the bug report for a clever hack to detect when the browser is shut down via a key press.
This one works for me:
chrome.windows.onRemoved.addListener(function(windowId){
alert("!! Exiting the Browser !!");
});
It takes chrome.windows rather than chrome.tabs.
TL;DR: Try window.onunload event, it works for some cases.
As it was mentioned before we generally can't handle something like onBrowserClose event and prevent browser from closing. But for some cases we can use window.onunload event for doing something synchronously, and it does work if it really synchronously.
From my experience you can at least:
Save some information in (for example logs) in HTML5 localStorage (which is synchronous).
Call some asynchronous chrome extension API functions but you can't get a result. (It works for me! Yay!)
Perform synchronous XMLHTTPRequest (yeah, sometimes it works).

Categories