Setting break point changes behavior of code - javascript

I'm attempting to implement the jquery.FileDownload plugin that allows for an Ajax-like file download experience that isn't normally possible by using iframes. The fact that I'm using this plugin isn't imperative to my question, however. This is a general question about break points in code.
That being the case, here is my code:
function generateReport(elementId, data, url) {
var $container = $(elementId);
$.fileDownload(url, {
httpMethod: 'POST',
data: data,
successCallback: function (url) {
$container.toggle('slow');
},
failCallback: function (responseHtml, url) {
$container.find('.error-message').removeClass('hide');
}
});
return false;
}
When the AJAX call is successful, successCallback is called and everything works properly. When a failure occurs in the request, failCallback is called and I am unable to access any elements in $container. I get a "Permission denied" error which may indicate something is going on regarding accessibility because of the iframe.
In either case, when debugging this issue, I put a break point in my browser debugger on the $.fileDownload() line. When I break on this line for any amount of time, $container and all of its containing elements are accessible and I don't get the "Permission denied" error. This is also the case when I break for any amount of time in the server-side method corresponding to url that is being passed into the $.fileDownload method.
This made me think there was a timing/threading issue with this plugin in IE. To recreate the delay that prevented the error from occurring in my debuggers, I tried to use setTimeout() and Thread.Sleep() in the javascript and server-side code respectively, but this still resulted in the "Permission denied" error.
What is different from breaking in the debuggers compared to manually adding a delay in the code?

Related

HtmlUnit JavaScript Issue on page load - Cannot find function

I'm crawling website secured with Cloudflare and sometimes getting an error due to redirection to page with ReCapcha, the page cannot be even loaded due to some javascript error. The code is failing on #getPage method and i have no idea why.
Here is the code works fine for normal pages, but fails on confirmation page:
final WebClient webClient = new WebClient(BrowserVersion.CHROME);
webClient.getOptions().setJavaScriptEnabled(true);
final HtmlPage page = webClient.getPage("https://mydummy.site");
webClient.waitForBackgroundJavaScript(10000);
int waitForBackgroundJavaScript = webClient.waitForBackgroundJavaScript(200);
int loopCount = 0;
while (waitForBackgroundJavaScript > 0 && loopCount < 2) {
++loopCount;
waitForBackgroundJavaScript = webClient.waitForBackgroundJavaScript(200);
if (waitForBackgroundJavaScript == 0) {
break;
}
}
Logs:
java.lang.RuntimeException: com.gargoylesoftware.htmlunit.ScriptException: Wrapped com.gargoylesoftware.htmlunit.ScriptException: Wrapped com.gargoylesoftware.htmlunit.ScriptException: TypeError: Cannot find function start in object [object MessagePort]. (https://www.gstatic.com/recaptcha/api2/v1536705955372/recaptcha__en.js#249) (https://www.gstatic.com/recaptcha/api2/v1536705955372/recaptcha__en.js#253)
at com.gargoylesoftware.htmlunit.html.HtmlPage.initialize(HtmlPage.java:305)
at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseInto(WebClient.java:539)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:399)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:316)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:467)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:449)
at Main.htmlUnit(Main.java:156)
at Main.main(Main.java:43)
Caused by: com.gargoylesoftware.htmlunit.ScriptException: Wrapped com.gargoylesoftware.htmlunit.ScriptException: Wrapped com.gargoylesoftware.htmlunit.ScriptException: TypeError: Cannot find function start in object [object MessagePort]. (https://www.gstatic.com/recaptcha/api2/v1536705955372/recaptcha__en.js#249) (https://www.gstatic.com/recaptcha/api2/v1536705955372/recaptcha__en.js#253)
at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine$HtmlUnitContextAction.run(JavaScriptEngine.java:892)
at net.sourceforge.htmlunit.corejs.javascript.Context.call(Context.java:616)
at net.sourceforge.htmlunit.corejs.javascript.ContextFactory.call(ContextFactory.java:532)
at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:772)
at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:748)
at com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine.execute(JavaScriptEngine.java:104)
at com.gargoylesoftware.htmlunit.html.HtmlPage.loadExternalJavaScriptFile(HtmlPage.java:992)
at com.gargoylesoftware.htmlunit.html.HtmlScript.executeScriptIfNeeded(HtmlScript.java:371)
at com.gargoylesoftware.htmlunit.html.HtmlScript$2.execute(HtmlScript.java:246)
at com.gargoylesoftware.htmlunit.html.HtmlPage.initialize(HtmlPage.java:298)
We have been struggling with this issue as well. Our test suite ran perfectly until late 2018 when this issue broke all of our logins. I believe Google has put this in deliberately to break automated attempts to break captchas, because solving one part of this seems to only lead to another problem. Both loading the page and submitting the page causes issues, even if you tell HtmlUnitDriver to ignore all JavaScript errors.
I have tried several options at this point. If you use the Google specified test site key, then the errors go away. So if you have full server-side control of how that site key is generated, you are OK. Remember to ensure that the test site key shows up again on validation errors and all similar use cases, otherwise you will get that error.
(Unfortunately for us, our login page is plain JSP and so implementing this is a headache unless we want to change the URL everywhere. Still debating what to do, for right now we do have a workable if ugly solution that involves some conditional logic on the page and catching JavaScript exceptions at other points in the test code.)

Chrome extension "Uncaught error: Invalid value" using the redirect rules

I am trying to write an extension that will download audio files when it detects them being requested by chrome. I am basing this project on the code of the two samples "Download_links" and "catifier" provided by Google. Here is what I currently have:
var RequestMatcher = chrome.declarativeWebRequest.RequestMatcher;
var IgnoreRules = chrome.declarativeWebRequest.IgnoreRules;
var RedirectRequest = chrome.declarativeWebRequest.RedirectRequest;
var songFileURL = "http://somefile.mp3";
...
function registerRules() {
var redirectRule = {
priority: 100,
conditions: [
new RequestMatcher({
contentType: ['audio/mp3']
}),
],
actions: [
chrome.downloads.download({url: songFileURL}),
]
};
...
When I load this up and try it out, I get an error: Uncaught Error: Invalid value for argument 1. Property '.0': Value does not match any valid type choices. No matter what I try I cannot figure out what is causing this error. I am fairly to Chrome extensions and JavaScript in general, so I am sure that this is an easy fix, but I cannot figure it out. Any ideas?
I think the problem is that you specify unsupported action. The list of available actions can be found on the chrome.declarativeWebRequest page.
I think you should use chrome.webRequest.onBeforeRequest, onHeadersReceived, or onComplete to trace media links and initiate custom downloads from there, possibly in some deferred way, because I'm not sure downloads will work just from another request handler.
To make a start you may have a look at Google's CatBlock example, or to another related answer or another one. Basically, you need to add appropriate event handler by means of addListener, and in the handler invoke chrome.downloads.download({url: request.url}), where the request is passed to the handler as input parameter.
Which one of events to choose (for example, onBeforeRequest or onComplete) you should decide based on your requirements. As I understand, you don't want to block original request, so it may be useful to wait utill original downloading is completed, and then process it in onComplete handler, so that Chrome would optimize the process by just copying already downloaded file from cache.
As alternative, you can block initial download by returning {cancel: true} from onBeforeRequest handler for every sound file, and then start your download as a single one, possibly with saveAs option involved.

Permission denied to call method ChromeWindow.postMessage for iframe inside XUL page

I've an extension, and an XUL file inside it (let's call it A). XUL file contains an <iframe>, where is loaded some web page (let's call it B). B is loaded from the different domain.
A is parent to B. I want to send a message from within B to A using window.parent.postMessage().
I'm getting the following exception:
... permission denied to B to call method ChromeWindow.postMessage
How to fix that error? If there is no way to do that, how can I pass message from B to A?
I am using Firefox 16.0.1 under Windows 7.
I had a very similar problem,
it's just I had a html-popup (local) that couldn't send 'postMessage' to my xul-background-task.
I think I got it to work,
strangely enough by initiating a MessageEvent of my own (the very same thing postMessage does)
but with a (I believe obsolete) fallback.. in short: I brewed something together from MDN and other sites ;)
My script in the content:
var Communicator =
{
postMessage: function(data)
{
// We need some element to attach the event to, since "window" wont work
// let's just use a fallback JSON-stringified textnode
var request = document.createTextNode(JSON.stringify(data));
// and as always attach it to the current contentwindow
document.head.appendChild(request);
// Now let's make a MessageEvent of our own, just like window.postMessage would do
var event = document.createEvent("MessageEvent");
event.initMessageEvent ("own_message", true, false, data, window.location, 0, window, null);
// you might want to change "own_message" back to "message" or whatever you like
//and there we go
request.dispatchEvent(event);
}
}
And instead of window.postMessage(data) now use Communicator.postMessage(data)
that's all!
Now in my overlay there's nothing but our good old
addEventListener('own_message', someMessageFunc, false, true);
//or maybe even "message" just like originally
Hopefully this will work for you, too (didn't check that on iframes...)
You should check the type of iframe B
Edit:
Apparently you must flag your chrome as contentaccessible, and take into consideration the security.
Just posting in case someone faced the same problem.
Succeeded in posting message from within B to A using events as described here.
But it is not answer, because window.parent.postMessage() still doesn't work as intended.

Problem using window.location in a function called from onsubmit

I'm currently creating a very small form on my homepage using HTML and JavaScript. I've run into a problem I'm pretty sure I could circumvent somehow (probably in a pretty ugly way though), but I got interested in why this error appears.
I have a form on my page which I specify in the following way:
<FORM name="form1" onsubmit="submitTheScript()">
The function "submitTheScript()" is placed in the header and reads:
setCookie("F_GivenSum", GivenSum);
window.location="LastScreen.html";
"setCookie()" is a function that basically just, well, creates a cookie :).
Now, the problem arises with the last line of code. I'm trying to send the user to another page, after the cookie has been set (I'm doing some controls that the input value is alright, but I've skipped that part here) but FireFox gives me the following error:
uncaught exception: [Exception... "Cannot modify properties of a WrappedNative" nsresult: "0x80570034 (NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN)" location: "JS frame :: chrome://global/content/bindings/autocomplete.xml :: onxblpopuphiding :: line 827" data: no]
I guess I can't call this function the way I do, from within a onsubmit command, however, I don't see why.
Okay, I did a quick test and found out that you need to assign the onsubmit event handler via javascript like so:
document.getElementById("myform").onsubmit = doSubmit;
function doSubmit() {
document.cookie = "F_GivenSum=200";
window.setTimeout(function() {
window.location = ('test2.html');
}, 20);
return false;
}
This did not give any errors in FF.

What is this obscure error in Google Analytics tracking code on a _trackEvent() call?

I am calling the Google Analytics _trackEvent() function on a web page, and get back an error from the obfuscated Google code. In Firebug, it comes back "q is undefined". In Safari developer console: "TypeError: Result of expression 'q' [undefined] is not an object."
As a test, I have reduced the page to only this call, and still get the error back. Besides the necessary elements and the standard Google tracking code, my page is:
<script>
pageTracker._trackEvent('Survey', 'Checkout - Survey', 'Rating', 3);
</script>
Results is that error.
What's going on here?
This problem seems to occure when the page is not fully loaded yet: http://www.google.com/support/forum/p/Google+Analytics/thread?tid=4596554b1e9a1545&hl=en
The provided solution is to wait for pageTracker.cb
function trackEvent(target, action, opt_label, opt_value) {
if(pageTracker && !pageTracker.cb) {
setTimeout(function() {
trackEvent(target, action, opt_label, opt_value);
}, 200);
return;
}
pageTracker._trackEvent(target, action, opt_label, opt_value);
}
Actually the answer no. 1 is not correct. That's because pageTracker.cb never gets set (it's an obfuscated property name) with other versions of GA.
You should call upon initialization:
pageTracker._initData()
This looks like a bug in ga.js introduced when they added _initData() functionality to _trackPageview(). Unfortunately _initData() isn't actually called after the conditional. Hope they fix it before they deprecate_initData() for good.
e.g.
This page suggests the above should work without calling _initData():
http://www.google.com/support/googleanalytics/bin/answer.py?hl=en&answer=55527

Categories

Resources