iMacros and socket.io - javascript

In my iMacros script I try to connect to a server using socket.io.
First I have to obtain the socket.io.js file, evaluate it and then use socket.io as normal.
Here is an excerpt from my script:
function loadScriptFromURL(url) {
try {
var request = Components.classes['#mozilla.org/xmlextras/xmlhttprequest;1'].createInstance(Components.interfaces.nsIXMLHttpRequest);
request.open('GET', url, false);
request.send();
if (request.status !== 200) {
var message = 'There was an error trying to connect to: ' + url + ', request status: ' + request.status;
iimDisplay(message);
}
eval(request.response);
} catch (e) {
window.console.log(e);
return false;
}
return true;
//alert(request.respsonse);
}
loadScriptFromURL('http://localhost:3700/socket.io/socket.io.js');
window.console.log(io.version); // returns 0.9.16
var socket = io.connect('http://localhost:3700');
The problem is that a Javascript code that is executed by iMacros is in the scope of the plugin (a sandbox), and when I use the io's connect method I get the "io.util is undefined" error.
Is there a way to populate this method so that iMacros could see it? I guess I need to make some changes in the socket.io.js file, but not quite sure yet...

I spent a couple of days to find a solution. I have another errors, for example "setTimeout() is not a function, Blob is not a function, diferent undefined errors..."
This occurs because the code is not running in the context of the current window.
Solution:
Go to "/node_modules/socket.io-client\socket.io.js"
It's client javascript code from url "http://localhost:3000/socket.io/socket.io.js"
Replace all:
"new Blob" -> "new window.Blob"
"instanceof Blob" -> "instanceof window.Blob"
And to do the same for:
Filereader - > window.Filereader
setTimeout() - > window.setTimeout()
clearTimeout() - > window.clearTimeout()
setTimeout() - > window.setTimeout()
It's working for me. Node.JS version is 5.3.0, Socket.IO version is 1.4.5.

Related

Javascript not working on mobile (Android) but fine on desktop

I've searched the archives but not found anything specific to my query.
In JavaScript I have a function with a callback function that fires a request at a postcode API to get coordinates for a postcode.
const getPostCodeLatLng = (strPostCode, callback) => {
alert("used API"); // !!! DOESN'T ALERT ON MOBILE !!!
const request = new XMLHttpRequest();
request.addEventListener('readystatechange', () => {
if(request.readyState == 4){
const jsnPostCode=JSON.parse(request.responseText);
callback(jsnPostCode);}});
request.open('GET', 'http://api.getthedata.com/postcode/' + strPostCode);
request.send();
};
and
getPostCodeLatLng(strInputFieldValue, (jsnPostCode) => { // use the function to get data about the postcode and callback to this function
if(jsnPostCode.status=="match"){
alert("used API"); // !!! DOESN'T ALERT ON MOBILE !!!
let strPostCodeLatLng = "LatLng(" + jsnPostCode.data.latitude + ", "
+ jsnPostCode.data.longitude + ")";
setFieldswithLatLng(strPostCodeLatLng);
objDisplayFindCons.value=`Postcode: ${strInputFieldValue}`;}
else objDisplayFindCons.value=`No match found for Postcode: ${strInputFieldValue}`;})
The functions work fine on a desktop but didn't work on either a Samsung phone nor tablet. I'm using Chrome on all devices.
The second section of code is part of a larger section that responds to an event where data is entered into a text box, validated as a possible postcode (using regex) and then requested as per the first function. The JSON text response is then parsed and checked to see if a match was found (the server returns valid JSON for unfound postcodes).
I am clear that it all works fine until it encounters the function call getPostCodeLatLng() where it never runs either of the alert("used API") statements on mobile.
I am new to JavaScript and finding coding callback functions and events challenging but I can't see any obvious bugs/reasons for this to fail on mobiles.
Are there known problems or limitations to what I'm doing?
Is there a way to workaround this or debug it effectively on mobile?
Please help!
Thanks,
Phil
So I tried various things and found the issue to be with using a http request.
Apparently from now on all requests from a Chrome browser on Android need to be https.
So changing request.open('GET', 'http://api.getthedata.com/postcode/' + strPostCode);
to request.open('GET', 'https://api.getthedata.com/postcode/' + strPostCode); fixed the problem straightaway.
Here is an article mentioning the change:-
https://www.thesslstore.com/blog/https-will-now-be-the-default-for-all-android-p-apps/
You live and learn...

Ajax Request in Progress suddenly started returning status = 0

I have a web project in PHP and it accesses a Java Project that uses the Restlet Framework. The web project is running on Apache and I am testing it using localhost. The Restlet Framework also uses localhost as the domain, but the url is slightly different: localhost:8888/
This is the Javascript that, using Ajax, makes a call to one of the Java classes (CollectionPublic) using the URL above.
var url = "<?php echo $config['restServer_url'] ?>collectionPublic";
var params= "pageList="+facebookPages+"&time="+time;
var client = new XMLHttpRequest();
client.open("POST", url,true);
client.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
client.onreadystatechange = function () {
if (client.readyState != 4) return;
if (client.status != 200 && client.status != 304) {
alert("error "+client.status);
} else {
alert("success");
}
callback(client);
}
if (client.readyState == 4) return;
client.send(params);
I have tested and the call is being made correctly, using the URL localhost:8888/collectionPublic, and it is reaching the CollectionPublic class (the class is working fine).
The PROBLEM is: When this call is made, the CollectionPublic class takes a long time to complete its task, and the user should be able to access other pages (on the same server) or reload the page. However, when either of these things happen, the alert("error "+client.status) pops up and the value of client.status is 0. The call is then aborted, but the CollectionPublic's task continue normally, and when it finishes, nothing happens in the web page (before, the alert("success") was being fired).
I spent hours trying to figure out what was causing the error, since this was working last week. Most of the posts I found said that it could be a Cross-Origin Resource problem, since localhost and localhost:8888 are not considered as the same domain. To see if that was really the problem, I started Chrome using the --disable-web-security argument (and it was really disabled) but the issue was still there.
The weirdest thing is that it has worked before, and I changed absolutely NOTHING in the code.
I have seen this post Reloading page while an Ajax request in progress gives empty response and status as zero and it seems quite similar to what I am facing.
Hopefully, I have made myself clear, but if you have any doubts regarding this issue, just ask.
Thanks a lot in advance.
I'm not convinced that the ajax request itself is quite right. if (client.readyState != 4) return; will always be true aside from when its actually 4. This may be better:
client.onreadystatechange = function () {
if(client.readyState < 4) {
//not complete yet
return;
}
if(client.status != 200 && client.status != 304) {
//an error
alert("error "+client.status);
return;
}
if(client.readyState === 4) {
//complete
callback(client);
}
}
As for the problem whereby the ajax call is aborted: This is correct behaviour. All XHR calls will be aborted by the browser as soon the page is reloaded or unloaded. Perhaps this was somehow not the case when viewing pages locally. I would not allow the user to navigate away (or reload) whilst the ajax in progress. As a work-around, your class could set a session variable that is read by your page.

Uncaught module xhr not found cordova-1.5.0.js

I am using phonegap cordova-1.5.0.js and jar.
and using the phonegap-plugins for cordova with jsOAtuh.1.3.3.js
I am getting error message:
"Uncaught module xhr not found at file:///android_asset/www/cordova-1.5.0.js"
whenever I am trying to create OAuth Object.
I have the following reference:
https://github.com/bytespider/jsoauth
Here is my code.
var config_google={
var config_google={
consumerKey: "{removed}",
consumerSecret: "{removed}",
requestTokenUrl: "https://www.google.com/accounts/OAuthGetRequestToken?scope={removed}",
authorizationUrl:"https://www.google.com/accounts/OAuthAuthorizeToken",
accessTokenUrl:"https://www.google.com/accounts/OAuthGetAccessToken"
};
function authservice(service){
//alert(service);
curfunc = "authservice";
str_service = service;
if (service === 'google'){
oauth = new OAuth(config_google);
}else if....
........
}
I used that code with phonegap-1.4.1.js(previous version) before and it works. and I searched xhr on both 1.4.1 and 1.5.0 they both don't have xhr in it but some commented references. Not exactly sure why changed the 1.5.0 and it will disable the code. and I need to use 1.5.0 is because I need to use the childbrowser plugins.
Would you able to point me to the right direction?
Thanks in advance.
I have a hack that got it to work. The require("xhr") at line 802 thinks someone, somewhere registered it, but in logging it, I don't see anyone ever calling Cordova's "define" function to register it.
So, if you comment out those 3 lines of code, it's a quick way to get it to fall back to XMLHttpRequest like so (around line 800 within Request constructor):
if (typeof global.Titanium !== 'undefined' && typeof global.Titanium.Network.createHTTPClient != 'undefined') {
XHR = global.Titanium.Network.createHTTPClient();
//} else if (typeof require !== 'undefined') {
// // CommonJS require
// XHR = new require("xhr").XMLHttpRequest();
} else {
// W3C
XHR = new global.XMLHttpRequest();
}

GET HTTPs request not working properly in phonegap

I'm running this app in an Android phone (Samsung Galaxy mini running on ANdroid 2.2). I'm using couchdb for my database and host it on cloudant.
On device ready, the app will make a get request to the https db server which contains feeds of data that i need to be displayed in my app. At first, it was working fine but when i try to post and add new data to my https db server, then trigger the get request method, the returned response from the server is still the same as before(the newly posted data was not included even though i checked my db server and saw that it was indeed saved). Then i tried to close and reopen the app again, which will then make a new instance of the get http request, but still, the response still is the same as the very first one and doesnt contain the new data that was added to the db server. Then, I tried to reinstall my app, then run the app again, and oddly enough, the response from the get request now contains the new data.. I don't know how that happens, and I'm not really experienced with REST api and javascript so I might be doing something obviously wrong. Here's a snippet of my code for the get request:
var getFeedsClient;
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
if (window.XMLHttpRequest) {
getFeedsClient=new XMLHttpRequest();
}
else {
getFeedsClient=new ActiveXObject("Microsoft.XMLHTTP");
}
try{
getFeedsRequest();
} catch(e)
{
alert("Error on device ready: "+e);
}
}//on Device Ready
function getFeedsRequest() {
getFeedsClient.onreadystatechange = getFeedsFunction;
getFeedsClient.open("GET","https://<username>.cloudant.com/te/_design/requestfeed/_view/all",true);
getFeedsClient.send();
}
function getFeedsFunction() {
alert(" readystate: "+getFeedsClient.readyState+", status: "+getFeedsClient.status);
if(getFeedsClient.readyState == 4 && getFeedsClient.status == 200 ) {
var data = JSON.parse(getFeedsClient.responseText);
console.log("RESPONSE FROM COUCHDB "+getFeedsClient.responseText);
console.log("JSON data "+data);
//at first the total rows is 2 but when a new data was added, the total rows should be three, but that was not the case
alert("rows: "+data.total_rows);
}
}
I ran into a similar issue last week of the device caching requests. I solved it by adding a dummy unique parameter to the link like below:
function getFeedsRequest() {
getFeedsClient.onreadystatechange = getFeedsFunction;
var link = "https://<username>.cloudant.com/te/_design/requestfeed/_view/all";
var unique = (new Date).getTime();
getFeedsClient.open("GET",link + '?' + unique,true);
getFeedsClient.send();
}
Paul Beusterien's solution below worked for me with the following caveat:
An android 4.0.4. phone did not need a unique URL, but the same code running on 2.2.2 did!

Catching same origin exception in Javascript?

I'm trying to create my own XMLHttpRequest framework to learn how this things work internally.
A thing that puzzles me is that I cannot find how to catch a "Same origin" exception.
The idea behind this is that I try to load a URL, if I get a Same origin exception, I re-request the URL through a proxy script local for the script. The reason I do this is because I need to access production data from a development sandbox and I want it to be as transparent as possible for the script itself.
I know it's a bad practice but this is the least intrusive way of doing this at the moment :)
Just to clear things - I don't want to bypass same origin, I just want to catch the thrown exception so I can do something about it.
Here is the code I currently use for my xhr:
var net = function (url, cb, setts){
this.url = url;
this.cb = cb;
var oThis = this;
if (!this.xhr) {
this.xhr = new XMLHttpRequest();
this.xhr.onreadystatechange = function() {
if (oThis.xhr.readyState == 4 && oThis.xhr.status == 200) {
document.body.innerHTML += "RS: "+oThis.xhr.readyState+"; ST:"+oThis.xhr.status+"; RP:"+oThis.xhr.responseText+"<br>";
}
else {
// do some other stuff :)
document.body.innerHTML += "RS: "+oThis.xhr.readyState+"; ST:"+oThis.xhr.status+"; RP:"+oThis.xhr.responseText+"<br>";
}
}
}
this.xhr.open("GET", url,true);
this.xhr.send();
} // It's WIP so don't be scared about the unused vars or hardcoded values :)
I've tried to try...catch around xhr.send(); but no avail, still can't catch the exceptions.
Any ideas or pointers would be greatly appreciated.
xhr.onreadystatechange = function() {
if (xhr.readyState==4) {
if (xhr.status==0) {
alert("denied");
} else {
alert("allowed");
}
}
}
Are you sure it's actually supposed to throw an exception? I can't see anything in the specifications: http://www.w3.org/TR/XMLHttpRequest/#exceptions Looks like it does. My bad.
In either case, you can always check the domain of the incoming string against the domain of the page the user is currently on.
FWIW, as you can see by this jsFiddle (open up Web Inspector), Chrome doesn't really throw an exception. It just says "Failed to load resource".

Categories