Getting requests from a website and retrieving the response? - javascript

I am trying to monitor a website (www.bidcactus.com). While on the website I open up Firebug, go to the net tab, and click the XHR tab.
I want to take the responses of the requests and save it to a mySql database (I have a local one running on my computer(XAMPP).
I have been told to do a variety of things mainly using jQuery or JavaScript but I'm not experienced either so I was wondering if anyone can help me out here.
Someone suggested me this link
Using Greasemonkey and jQuery to intercept JSON/AJAX data from a page, and process it
Its using Greasemonkey as well which I don't know much about either...
Thanks in advance for any help
Example/more detail:
While monitoring the requests sent(via firebug) I see below
http://www.bidcactus.com/CactusWeb/ItemUpdates?rnd=1310684278585
The response of this link is the following:
{"s":"uk5c","a":[{"w":"MATADORA","t":944,"p":5,"a":413173,"x":10},
{"w":"1000BidsAintEnough","t":6,"p":863,"a":413198,"x":0},
{"w":"YourBidzWillBeWastedHere","t":4725,"p":21,"a":413200,"x":8},
{"w":"iwillpay2much","t":344,"p":9,"a":413201,"x":9},
{"w":"apcyclops84","t":884,"p":3,"a":413213,"x":14},
{"w":"goin_postal","t":165,"p":5,"a":413215,"x":12},
{"w":"487951","t":825,"p":10,"a":413218,"x":6},
{"w":"mishmash","t":3225,"p":3,"a":413222,"x":7},
{"w":"CrazyKatLady2","t":6464,"p":1,"a":413224,"x":2},
{"w":"BOSS1","t":224,"p":102,"a":413230,"x":4},
{"w":"serbian48","t":62,"p":2,"a":413232,"x":11},
{"w":"Tuffenough","t":1785,"p":1,"a":413234,"x":1},
{"w":"apcyclops84","t":1970,"p":1,"a":413240,"x":13},
{"w":"Tuffenough","t":3524,"p":1,"a":413244,"x":5},
{"w":"Cdm17517","t":1424,"p":1,"a":413252,"x":3}],"tau":"0"}
I understand what this information and I think I could format it myself however the website randomly creates new requests.
Example http://www.bidcactus.com/CactusWeb/ItemUpdates?rnd=XXXXXXXXXXXX
and I'm not sure how it creates them.
So I'm needing to get the response for all the requests that are for item updates and send the information to a mysql database.

OK, here's working code, somewhat tuned for that site (front page, no account, only).
Instructions for use:
Install the GM script. Note that it is Firefox only, for now.
Observe it running in Firebug's console, and tune the filter section (clearly marked), to target the data you are interested in. (Maybe the whole a array?)
Note that it can take several seconds after "Script Start" is printed, for the ajax intercepts to start.
Setup your web application and server to receive the data. The script posts JSON, so PHP, for example, would grab the data, like so:
$jsonData = json_decode ($HTTP_RAW_POST_DATA);
Point the script to your server.
VoilĂ . She is done.
/******************************************************************************
*******************************************************************************
** This script intercepts ajaxed data from the target web pages.
** There are 4 main phases:
** 1) Intercept XMLHttpRequest's made by the target page.
** 2) Filter the data to the items of interest.
** 3) Transfer the data from the page-scope to the GM scope.
** NOTE: This makes it technically possibly for the target page's
** webmaster to hack into GM's slightly elevated scope and
** exploit any XSS or zero-day vulnerabilities, etc. The risk
** is probably zero as long as you don't start any feuds.
** 4) Use GM_xmlhttpRequest () to send the data to our server.
*******************************************************************************
*******************************************************************************
*/
// ==UserScript==
// #name _Record ajax, JSON data.
// #namespace stackoverflow.com/users/331508/
// #description Intercepts Ajax data, filters it and then sends it to our server.
// #include http://www.bidcactus.com/*
// ==/UserScript==
DEBUG = true;
if (DEBUG) console.log ('***** Script Start *****');
/******************************************************************************
*******************************************************************************
** PHASE 1 starts here, this is the XMLHttpRequest intercept code.
** Note that it will not work in GM's scope. We must inject the code to the
** page scope.
*******************************************************************************
*******************************************************************************
*/
funkyFunc = ( (<><![CDATA[
DEBUG = false;
//--- This is where we will put the data we scarf. It will be a FIFO stack.
payloadArray = []; //--- PHASE 3a
(function (open) {
XMLHttpRequest.prototype.open = function (method, url, async, user, pass)
{
this.addEventListener ("readystatechange", function (evt)
{
if (this.readyState == 4 && this.status == 200) //-- Done, & status "OK".
{
var jsonObj = null;
try {
jsonObj = JSON.parse (this.responseText); // FF code. Chrome??
}
catch (err) {
//if (DEBUG) console.log (err);
}
//if (DEBUG) console.log (this.readyState, this.status, this.responseText);
/******************************************************************************
*******************************************************************************
** PHASE 2: Filter as much as possible, at this stage.
** For this site, jsonObj should be an object like so:
** { s="1bjqo", a=[15], tau="0"}
** Where a is an array of objects, like:
** a 417387
** p 1
** t 826
** w "bart69"
** x 7
*******************************************************************************
*******************************************************************************
*/
//if (DEBUG) console.log (jsonObj);
if (jsonObj && jsonObj.a && jsonObj.a.length > 1) {
/*--- For demonstration purposes, we will only get the 2nd row in
the `a` array. (Probably stands for "auction".)
*/
payloadArray.push (jsonObj.a[1]);
if (DEBUG) console.log (jsonObj.a[1]);
}
//--- Done at this stage! Rest is up to the GM scope.
}
}, false);
open.call (this, method, url, async, user, pass);
};
} ) (XMLHttpRequest.prototype.open);
]]></>).toString () );
function addJS_Node (text, s_URL)
{
var scriptNode = document.createElement ('script');
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
var targ = document.getElementsByTagName('head')[0] || d.body || d.documentElement;
targ.appendChild (scriptNode);
}
addJS_Node (funkyFunc);
/******************************************************************************
*******************************************************************************
** PHASE 3b:
** Set up a timer to check for data from our ajax intercept.
** Probably best to make it slightly faster than the target's
** ajax frequency (about 1 second?).
*******************************************************************************
*******************************************************************************
*/
timerHandle = setInterval (function() { SendAnyResultsToServer (); }, 888);
function SendAnyResultsToServer ()
{
if (unsafeWindow.payloadArray) {
var payload = unsafeWindow.payloadArray;
while (payload.length) {
var dataRow = JSON.stringify (payload[0]);
payload.shift (); //--- pop measurement off the bottom of the stack.
if (DEBUG) console.log ('GM script, pre Ajax: ', dataRow);
/******************************************************************************
*******************************************************************************
** PHASE 4: Send the data, one row at a time, to the our server.
** The server would grab the data with:
** $jsonData = json_decode ($HTTP_RAW_POST_DATA);
*******************************************************************************
*******************************************************************************
*/
GM_xmlhttpRequest ( {
method: "POST",
url: "http://localhost/db_test/ShowJSON_PostedData.php",
data: dataRow,
headers: {"Content-Type": "application/json"},
onload: function (response) {
if (DEBUG) console.log (response.responseText);
}
} );
}
}
}
//--- EOF
Misc notes:
I tested it on the main page of that site, without logging in (I'm not about to to create an account there).
I tested with AdBlock, FlashBlock, NoSCript, and RequestPolicy all in full effect. JS was turned on for bidcactus.com (it has to be) but no others. Turning all that crud back on shouldn't cause side effects -- but if it does, I'm not going to debug it.
Code like this has to be tuned for the site and for how you browse said site1. It's up to you to do that. Hopefully the code is self-documented enough.
Enjoy!
1 Mainly: the #include and #exclude directives, the JSON data selection and filtering, and whether iFrames need to be blocked. Also it is recommended that the 2 DEBUG variables (one for GM scope and one for the page scope) be set to false when the tuning is done.

This isn't achievable with javascript/jquery's ajax request, because of Same origin policy
I'm not experienced with greasemonkey, through

Related

Recent Firefox breaks existing converted Chrome extension

I have a Chrome-based extension which works unfailingly in Chrome 26 through Chrome 70. It continues to work exactly as it does in Chrome in Firefox 47, 48, 49, but is now broken in FF/DevEdition 64.
I have no clue where to begin to look at what incompatibility FF later versions introduced/broke basic functions that worked in 47,48,49? Any pointers will be appreciated (even a link to archived versions in between so that I can grab a spare 'puter and find the exact version where it fails).
update: this is the daemon (background pg) code which opens the GUI interface
(excerpted):
var fireflyID = 0;
/* ... */
// msgpath 'class' [creates a bridge between the SDK (the GUI)
// and the tab it monitor/analyses/debugs ...
var msgpath = function(pathid, pathname, tabID, url, opener, reply) {
/* ... */
this.pathname = pathname;
this.sdk.path = url;
this.tab.tabID = tabID;
this.tab.port = chrome.tabs.connect(tabID);
this.tab.port.onMessage.addListener(handleSCRMsg);
/* ... */
this.connect = function() { //opening handshake with contentscr
this.tab.port.postMessage( {"msgtype":"connect" /* ... */};
};
this.accept = function() { //handshake accepted, open the sdk...
var fireflyURL;
fireflyURL = chrome.runtime.getURL(this.sdk.path);
// this works in Chrome26-Chrome70 (latest version)
// and Firefox 47-55, it opens the panel in FF56+,
// applies the title, but never displays the content?
// and yes .getURL() does add the right 'protocol' to the url
this.sdk.wdw = chrome.windows.create( {
"url" : fireflyURL +
"?portname=" + this.pathname + ";opener=",
"width" : 980,
"height" : 720,
"type" : "panel"
});
};
/* ... */
};
/* ... */
// msg from content-script...
var handeSCRMsg = function(msg) {
var mpath = null;
if (msg.msgpath) {
mpath = msgpaths[msg.msgpath];
/* ... */ // content scr accepts connection
if (msg.msgtype == "accept")
mpath.accept(); // msgpath object 'class' from above
/* ... */ // go open the sdk and splice the port connections
}
};
var handleCTRLMsg = function(msg) {
/* ... */
if (msg.msgtype == "open") {
pathid = fireflyID++;
pathname = "firefly"+pathid;
mpath = new msgpath(pathid, pathname, msg.tabID,
msg.path, msg.parent, msg.reply);
mpath.connect();
};
// wake up on pageAction (extension icon click)
chrome.pageAction.onClicked.addListener( function(tab) {
/* ... */
msg.tabID = tab.id;
msg.path = "sdkfirefly.html";
handleCTRLMsg(msg);
};
// content scr posts msg to daemon to tell daemon
// that dflibg dataflow library is in application
// 'tab' and it is ok to enable pageAction/icon
chrome.runtime.onMessage.addListener ( function (msg, sender) {
/* ... */
tab = sender.tab;
if (msg.msgtype == "activate")
chrome.pageAction.show(tab.id);
}
and that shows the pertinent logic/msg flow.
It is pretty basic stuff, and since it works in so many other instances
I'm rather confused as to where to investigate next.
Further update: Console log shows some firefox-internal xml errors - anything else is at the warning level (ff not paying attention to the manifest version number, or mis-processing the manifest) or a ff error [e.g., it complains about "browser-style" missing, but its there in page_action as it is supposed to be; then it complains about background.persistent but that is not there and does not apply to FF anyway...] None of this is material as the following seems to be the crux of the issue:
Upon further testing:
Extension loads and runs in FF47-FF55 on all platforms. Appears to not finish loading in FF56+ in Windows, but loads and runs as expected in FF47-FF64 on Linux.
The extension gui does [eventually] load in Win10/FF56 (i7-7700/3.6), but takes (wait for it) over 12 minutes for FF to load it (which makes it appear broken -- it takes 1/2 sec or less in Linux [ on an amd X4 860K], or 40 secs +/- in Win7 (i7-6700/3.4). Part of this is that there is something really wrong with the FF ipc mechanism used as a foundation layer for messaging between a tab and an extension page -->> it takes 14 secs for a round trip msg between the GUI->daemon->content-script->library, library->content_script->daemon->GUI (six hops total)
in win10/FF but it only takes millisecs in linux.
It appears that something radically changed between FF55 and FF56+ on Window$64bit platforms. Does anyone have a clue as to the difference, or a work-around using something other than the port ipc mechanism?
Thanks
After extensive testing, the problem appears to be how FF56 and newer interface with Windows7/10 to access the components of the extension - IFF the extension was loaded from a NAS/Samba or NFS mounted share. Why this has any effect on ipc as well is a complete mystery.
The solution is to copy the extension from the NAS appliance or Samba/NFS mounted share
to a physically local hard drive and temp-load the extension from there.

TamperMonkey - message between scripts on different subdomains

I have two scripts. Each runs on a different subdomain of our company "Example.com".
Script #1 -- house.example.com
Script #2 -- bob.fred.example.com
Same domain, different subdomains.
When a particular element appears on house.example.com, I need to send a message over to the script running on bob.fred.example.com
Since Google extensions can exchange messages between extensions, there must be a way with TamperMonkey to exchange messages within the same extension, between scripts -- especially if they run on the same second-level domain.
Can anyone point me in the right direction? An example or two would be worth their weight in gold.
Update: Although Gothdo referenced Javascript communication between browser tabs/windows as containing an answer to this question, he failed to take into consideration the cross-origin policies involved. None of the answers in that referenced question provide a clear answer for cross-origin browser tab communications, which was the main point of this question. I have now researched and solved this problem, getting ideas from a number of SO and non-SO sources. If this question is re-opened, I will post my solution.
You can use GM_getValue, GM_setValue & GM_addValueChangeListener to achieve cross-tab user script communication.
Add the following lines in your user script header.
// #grant GM_setValue
// #grant GM_getValue
// #grant GM_addValueChangeListener
The following lines of rough code will simplify the cross-tab user script communication.
function GM_onMessage(label, callback) {
GM_addValueChangeListener(label, function() {
callback.apply(undefined, arguments[2]);
});
}
function GM_sendMessage(label) {
GM_setValue(label, Array.from(arguments).slice(1));
}
So all you'll need to do is the following to send and receive messages.
GM_onMessage('_.unique.name.greetings', function(src, message) {
console.log('[onMessage]', src, '=>', message);
});
GM_sendMessage('_.unique.name.greetings', 'hello', window.location.href);
NOTE Sending messages may not trigger your callback if the message sent is the same as before. This is due to GM_addValueChangeListener not firing because the value has not changed, i.e. same value as before even though GM_setValue is called.
Using #grant enables the sandbox, which can sometimes result in difficulties when trying to interact with complicated page objects on Greasemonkey.
If you do not want to enable the sandbox with #grant, another option is to have the userscript create an iframe to the other domain, and then post a message to it. On the other domain, in the iframe, listen for messages. When a message is received, use BroadcastChannel to send the message to every other tab on that other domain, and your other tabs with the userscript running can have the same BroadcastChannel open and listen for messages.
For example, to create a userscript on stackoverflow.com that can send a message to a userscript running in a different tab on example.com:
// ==UserScript==
// #name 0 Cross-tab example
// #include /^https://example\.com\/$/
// #include /^https://stackoverflow\.com\/$/
// #grant none
// ==/UserScript==
if (window.location.href === 'https://example.com/') {
const broadcastChannel = new BroadcastChannel('exampleUserscript');
if (window.top !== window) {
// We're in the iframe:
window.addEventListener('message', (e) => {
if (e.origin === 'https://stackoverflow.com') {
broadcastChannel.postMessage(e.data);
}
});
} else {
// We're on a top-level tab:
broadcastChannel.addEventListener('message', (e) => {
console.log('Got message', e.data);
});
}
} else {
// We're on Stack Overflow:
const iframe = document.body.appendChild(document.createElement('iframe'));
iframe.style.display = 'none';
iframe.src = 'https://example.com';
setTimeout(() => {
iframe.contentWindow.postMessage('Sending message from Stack Overflow', '*');
}, 2000);
}
This results in:
If you want two-way communication, not just one-way communication, have both parent pages create a child iframe to a single target domain (say, to example.com). To communicate to other tabs, post a message to the child iframe. Have the child iframe listen for messages, and when seen, post a BroadcastChannel message to communicate with all other iframes. When an iframe receives a BroadcastChannel message, relay it to the parent window with postMessage.
// ==UserScript==
// #name 0 Cross-tab example
// #include /^https://example\.com\/$/
// #include /^https://(?:stackoverflow|stackexchange)\.com\/$/
// #grant none
// ==/UserScript==
if (window.location.href === 'https://example.com/') {
const broadcastChannel = new BroadcastChannel('exampleUserscript');
if (window.top !== window) {
// We're in an iframe:
window.addEventListener('message', (e) => {
console.log('iframe received message from top window');
if (e.origin === 'https://stackoverflow.com' || e.origin === 'https://stackexchange.com') {
broadcastChannel.postMessage(e.data);
}
});
broadcastChannel.addEventListener('message', (e) => {
console.log('iframe received message from BroadcastChannel');
window.top.postMessage(e.data, '*');
});
}
} else {
// We're on Stack Overflow or Stack Exchange
const iframe = document.body.appendChild(document.createElement('iframe'));
iframe.style.display = 'none';
iframe.src = 'https://example.com';
window.addEventListener('message', (e) => {
if (e.origin === 'https://example.com') {
console.log(`Top window ${window.origin} received message from iframe:`, e.data);
}
});
if (window.location.href === 'https://stackoverflow.com/') {
setTimeout(() => {
console.log('stackoverflow posting message to iframe');
iframe.contentWindow.postMessage('Message from stackoverflow', '*');
}, 2000);
}
}
In the above code, a tab on Stack Overflow sends a message to a tab on Stack Exchange. Result screenshot:
The method I ended up using for tab-to-tab communication between subdomains on the same domain was to pass information via javascript cookies. (I also tried using localStorage, but that didn't work between subdomains.)
Scenario: Tab A on SubDomain A will send messages to Tab B on SubDomain B:
Code looked like this:
function getCookie(cooVal) {
var cname = cooVal+ '=';
var ca = document.cookie.split(';');
for (var i=0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(cname) === 0) {
return c.substring(cname.length, c.length);
}
}
return null;
} //END getcookie()
Tab B on subDomainB would RECEIVE messages from TabA on subDomain A:
function checkIncomingCIQ(){
var acciq = getCookie('acciq');
var jdlwc = getCookie('jdlwc');
}
TabA would SEND messages to Tab B like this:
document.cookie="acciq=5; domain=.example.com; path=/";
document.cookie="jdlwc=fubar; domain=.example.com; path=/";
For anyone wondering, yes, the subdomains can send messages to one another - it is not only a one-way communication. Just duplicate the same scenario in the other direction as well.
Of course, on both tabs the messaging system would be inside a javascript loop, like this:
(function foreverloop(i) {
//Do all my stuff - send/receive the cookies, do stuff with the values, etc
setTimeout(function() {
foreverloop(++i);
},2000);
}(0)); //END foreverloop
The TM headers on both tabs look like this:
// ==UserScript==
// #namespace abcd.tops.example.com
// #match *://abcd.tops.example.*/*
// #grant none
// #require http://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js
// ==/UserScript==
and
// ==UserScript==
// #namespace http://mysubdomain.example.com/callcenter/
// #match *://*.example.com/callcenter/
// #grant none
// #require http://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js
// ==/UserScript==
Apologies to all for the delay posting this solution. It took so long for the question to be re-opened after it was wrongly marked as duplicate that life went on . . .

Load a javascript resource from an external source, when it's blocked with a 403 status

For some reason my ISP is blocking the following URL:
http://assets.tumblr.com/javascript/prototype_and_effects.js
Chrome console states:
Failed to load resource: the server responded with a status of 403 (URLBlocked)
The result is I can't use Tumblr properly because many functions depend on this script. I have already contacted my ISP and asked them to stop blocking this URL, but meanwhile I would like to do something about it.
How can I load this resource externally? It could be a bookmarklet solution, userscript/Greasemonkey or any other thing you can think of.
A 403 status means that the server (assets.tumblr.com) blocked the request, not your ISP. The most common reasons a server does this are (a) because you've not logged in with sufficient access, and/or (b) The server didn't receive the referrer header and/or cookies it wanted, and/or (c) the request came from an IP address that the server has blacklisted. Using a proxy server can trigger any or all of these for some sites.
This means that if you, or your proxy server, are being blocked from that file, then the standard methods of injecting remote javascript, that a userscript would use, will also be blocked.
To get around this Greasemonkey can backfill the javascript file from a local copy. To do this:
Create the file, Insure Tumbler has prototype.user.js, as shown below. Place it in a directory that is not in a temp folder on your machine.
Download the prototype_and_effects.js file you referenced and place it in the same folder. You may have to use a different (or no proxy), or a different browser profile, or whatever. (It downloads just fine, for me, just by right-clicking the immediately-preceding link.)
Install the script with Greasemonkey. (Firefox: File -> Open (CtrlO) will work.)
The script tests for the Prototype and Effect libraries and loads them locally if one is missing. There may be more required to get Tumblr working again but, if so, that is beyond the scope of this question.
Works in Firefox+Greasemonkey. Should work in Chrome+Tampermonkey (not tested), Will not work where #resource is not supported, such as straight Chrome.
// ==UserScript==
// #name _Backfill Prototype and Effect libraries on Tumblr pages
// #match http://tumblr.com/*
// #match http://www.tumblr.com/*
// #match https://tumblr.com/*
// #match https://www.tumblr.com/*
// #resource PandE_src prototype_and_effects.js
// #grant GM_getResourceText
// ==/UserScript==
//-- Does this page load prototype_and_effects.js?
var protoScriptNode = document.querySelector ("script[src*='prototype_and_effects']");
if (protoScriptNode) {
//console.log ("Page uses prototype_and_effects.js.");
//-- Are Prototype and Effects loaded?
var P = unsafeWindow.Prototype;
var E = unsafeWindow.Effect;
if (P && P.Version && E && E.BlindDown) {
//console.log ("Everything's loaded, no action needed.");
}
else {
//console.log ("Loading prototype_and_effects.js");
var PandE_src = GM_getResourceText ("PandE_src");
var scriptNode = document.createElement ('script');
scriptNode.type = "text/javascript";
scriptNode.textContent = PandE_src;
var targ = document.getElementsByTagName ('head')[0];
targ.appendChild (scriptNode);
}
}
else {
//-- No action needed
//console.log ("Page doesn't use prototype_and_effects.js.");
}

The request is too large for IE to process properly

I am using Websync3, Javascript API, and subscribing to approximately 9 different channels on one page. Firefox and Chrome have no problems, but IE9 is throwing an alert error stating The request is too large for IE to process properly.
Unfortunately the internet has little to no information on this. So does anyone have any clues as to how to remedy this?
var client = fm.websync.client;
client.initialize({
key: '********-****-****-****-************'
});
client.connect({
autoDisconnect: true,
onStreamFailure: function(args){
alert("Stream failure");
},
stayConnected: true
});
client.subscribe({
channel: '/channel',
onSuccess: function(args) {
alert("Successfully connected to stream");
},
onFailure: function(args){
alert("Failed to connect to stream");
},
onSubscribersChange: function(args) {
var change = args.change;
for (var i = 0; i < change.clients.length; i++) {
var changeClient = change.clients[i];
// If someone subscribes to the channel
if(change.type == 'subscribe') {
// If something unsubscribes to the channel
}else{
}
}
},
onReceive: function(args){
text = args.data.text;
text = text.split("=");
text = text[1];
if(text != "status" && text != "dummytext"){
//receiveUpdates(id, serial_number, args.data.text);
var update = eval('(' + args.data.text + ')');
}
}
});
This error occurs when WebSync is using the JSON-P protocol for transfers. This is mostly just for IE, cross domain environments. Meaning websync is on a different domain than your webpage is being served from. So IE doesn't want do make regular XHR requests for security reasons.
JSON-P basically encodes the up-stream data (your 9 channel subscriptions) as a URL encoded string that is tacked onto a regular request to the server. The server is supposed to interpret that URL-encoded string and send back the response as a JavaScript block that gets executed by the page.
This works fine, except that IE also has a limit on the overall request URL for an HTTP request of roughly 2kb. So if you pack too much into a single request to WebSync you might exceed this 2kb upstream limit.
The easiest solution is to either split up your WebSync requests into small pieces (ie: subscribe to only a few channels at a time in JavaScript), or to subscribe to one "master channel" and then program a WebSync BeforeSubscribe event that watches for that channel and re-writes the subscription channel list.
I suspect because you have a key in you example source above, you are using WebSync On-Demand? If that's the case, the only way to make a BeforeSubscribe event handler is to create a WebSync proxy.
So for the moment, since everyone else is stumped by this question as well, I put a trap in my PHP to not even load this Javascript script if the browser is Internet Destroyer (uhh, I mean Internet Explorer). Maybe a solution will come in the future though.

Ajax in Internet Explorer 9 slow after refresh

I'm working on a client-side webapplication that makes heavy use of JavaScript and Ajax to provide the required functionality.
This is not a problem for most browsers (Chrome, Firefox, ...), but in Internet Explorer the performance is a major issue.
It takes less than a second to load the page initially, even on Internet Explorer. But upon refreshing the page it can take anywhere between 1 and 20 seconds to load and display the page.
It's hard to post code since the application is divided into multiple files. I can only explain the intended behaviour.
The application initializes two content containers, one for static content and one for dynamic content. Each of these content containers is populated via Ajax and affects DOM elements via the innerHTML attribute.
The first time it takes less than a second to build the page. Subsequent refreshes take significantly longer.
What changes between the initial loading of the page and the refreshing of the page to explain this enormous performance drop? Do I need to uninitialize something on unloading the page?
Communication.request = function (method, target, async, data, callback) {
var types = ['string', 'string', 'boolean', 'null', 'null']; // Parameter types
if (data) { // Data was provided
types[3] = 'string'; // Data must be a string
}
if (callback) { // Callback was provided
types[4] = 'function'; // Callback must be a function
}
if (Utils.hasParams(arguments, types)) { // All the required parameters were provided and of the right type
var request = new XMLHttpRequest(); // Create a new request
request.open(method, target, async); // Open the request
if (callback) { // Callback was provided
request.handleCallback(callback); // Register the callback
}
if (data) { // Data was provided
var contentType = 'application/x-www-form-urlencoded'; // Prepare the content type
request.setRequestHeader('Content-Type', contentType); // Add a content type request header
}
request.send(data); // Send the request
}
};
The problem appeared to be related to the amount of concurrent connections. Depending on the connection / type of web server this is limited to 2 or 4 concurrent connections in Internet Explorer.
After clamping the number of connections to 2 the problem ceased to occur. Other browsers appear to have higher limits, though I have limited those to 4 just in case.
Also, the amount of concurrent messages is the amount of messages in-flight at any given time. This was previously unlimited and that made Internet Explorer quite sad :-(

Categories