Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert Msxml2.XMLHTTP based IE-only website so it also work with Firefox?

This is an IE-only website, which I want to use with other browsers, for example Firefox:

https://golestan.sbu.ac.ir/Forms/AuthenticateUser/login.htm

I am forced to use this website for my university. It uses Msxml2.XMLHTTP, which is an IE-only feature. I tried to convert it to XMLHttpRequest so it works on Firefox only. This is the Greasemonkey script I've created. Now it does not give error, but it does not work. All the functions come from the original script of the website, but they are changed so that they work with XMLHttpRequest. If the login script comes up, I'm ok with it. How can I debug this javascript?

// ==UserScript==
// @name        Golestan Login
// @namespace   sbu.ac.ir
// @include     https://golestan.sbu.ac.ir/Forms/AuthenticateUser/login.htm
// @version     1
// @grant       none
// ==/UserScript==

var isInternetExplorer = 0;

function check(){
  var x;
if (window.XMLHttpRequest) {
  x = new XMLHttpRequest();
} else {
  try { 
    x = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try { 
      x = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {
      x = false; 
    }
  }
}
  x.open("HEAD",document.location,true);
  x.send();
  var sd=new Date(x.getResponseHeader('Last-Modified'));
  var cd=new Date(document.lastModified);
  if(sd-cd>3660000){
    document.cookie = "reloading=1";
    window.location.reload(true);
    return false;
  }
  return true;
}


        function a(){
            for (k = 0; k < nall; k++) {
                td = document.createElement('TD');
                td.className = 'e';
                Pr.appendChild(td);
            }
            if (!check()) {
                //window.open("/_Templates/howtoclearcache.htm","_blank");
                //top.close();
                return;
            }
            var aCookie = document.cookie.split("; ");
            var cook=0;
            for (var i=0; i < aCookie.length; i++)
            {
                var aCrumb = aCookie[i].split("=");
                if ("reloading" == aCrumb[0]) {
                    cook=unescape(aCrumb[1]);
                    break;
                }
            }
            var ind=0;
            for( i=0;i<all.length;i=i+2){
                if(all[i+1]==1)
                    for(j=0;j<4;j++){
  var r;
if (window.XMLHttpRequest) {
  r = new XMLHttpRequest();
} else {
  try { 
    r = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try { 
      r = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {
      r = false; 
    }
  }
}


                        r.open("GET", all[i]+imstat[j]+".gif", true);
                        if(cook==1) r.setRequestHeader('If-Modified-Since','Sat,01 Jan 2000 00:00:00 GMT');
                        getobj(r,ind++);
                    }
                else{
  var r;
if (window.XMLHttpRequest) {
  r = new XMLHttpRequest();
} else {
  try { 
    r = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try { 
      r = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {
      r = false; 
    }
  }
}                   r.open("GET", all[i], true);
                    if(cook==1) r.setRequestHeader('If-Modified-Since','Sat,01 Jan 2000 00:00:00 GMT');
                    getobj(r,ind++);
                }
            }
            document.cookie = "reloading=0; expires=Fri, 31 Dec 1999 23:59:59 GMT;";
        }

function main_DoFSCommand(command, args) {
    var mainObj = document.all.main;
    //
    // Place your code here.
    //
    document.getElementById("rdir").style.visibility = "hidden";
    if(command != "showmenu")
    if(command == "Animation_Complete")
    {
        var x = 0;
        var y = 0;
        x = main.clientHeight/2 - 300;
        y = main.clientWidth/2 - 400;
        document.getElementById("iframeNews").style.top = x + 120;
        document.getElementById("iframeNews").style.left = y + 264;
        modifySrc();
        document.getElementById("iframeNews").style.visibility = "visible";

    }
    else
    {
        if(command == "Enter")
        {
            bal('main');
        }
        else if(command == "Education")
        {
            bal('test');
        }
        else
            document.getElementById("iframeNews").style.visibility = "hidden";
    }
}

// http://stackoverflow.com/questions/21271997
addJS_Node (check);
addJS_Node (a);
addJS_Node (main_DoFSCommand);

isInternetExplorer=true;

function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
    var D                                   = document;
    var scriptNode                          = D.createElement ('script');
    if (runOnLoad) {
        scriptNode.addEventListener ("load", runOnLoad, false);
    }
    scriptNode.type                         = "text/javascript";
    if (text)       scriptNode.textContent  = text;
    if (s_URL)      scriptNode.src          = s_URL;
    if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';

    var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
    targ.appendChild (scriptNode);
}

I think this work is worth doing, because hundreds of thousans of users, which are university students, are affected.

Update: We could be able to go one level further, and reach main.htm. So, I wrote another script for this page. But, at last I get ReferenceError: element is not defined[Learn More].

// ==UserScript==
// @name        Golestan Main
// @namespace   sbu.ac.ir
// @include     https://golestan.sbu.ac.ir/Forms/AuthenticateUser/main.htm
// @version     1
// @grant       none
// ==/UserScript==

// Microsoft WebService Behavior (Predecessor of modern AJAX)
// Information: https://web.archive.org/web/20060101200359/https://msdn.microsoft.com/workshop/author/webservice/webservice.asp
// JavaScript version: https://raw.githubusercontent.com/nzakas/professional-javascript/master/edition1/ch17/webservice.htc

// NOTE: You should paste the Javascript code from the above URL here

// end Microsoft WebService Behavior


function l(){
            useService("../f0241_process_authexit/authexit.asmx?WSDL", "get");
//            useService("authuser.asmx?WSDL", "get");
            mt = new MainTit(document,titH);
            mt.Maxi();
            t = new Tab(document,titH,0,document.body.clientWidth,document.body.clientHeight-titH);
            t.maintitle=mt;
            OpenFaci('صفحه اصلي','nav.htm?fid=0;1&tck='+'&'+location.search.replace('?',''));
            mt.HideGTit();
            KeysValues = location.search.split(/[\?&]+/);
            for (i = 0; i < KeysValues.length; i++) {
                    KeyValue = KeysValues[i].split("=");
                    if (KeyValue[0] == "CSURL") {
                        CSURL = KeyValue[1];
                        break;
                    }
            }
        }

function ex(ltck,tck,u,si,ft,fid,sess){
            var co = createCallOptions();
                co.funcName = "ex";
                co.async = false;
            // callService(function(result){if(result.error){/*alert(result.errorDetail.string);*/}},"ex",ltck,tck,u,si,ft,fid,sess);
                callService(co,ltck,tck,u,si,ft,fid,sess);

}


addJS_Node (l);
addJS_Node (ex);

addJS_Node(ErrDetail);
addJS_Node(postError);
addJS_Node(returnError);
addJS_Node(createCallOptions);
addJS_Node(createUseOptions);
addJS_Node(cloneObject);
addJS_Node(ensureVBArray);
addJS_Node(encb64hlp);
addJS_Node(decb64hlp);
addJS_Node(encb64);
addJS_Node(decb64);
addJS_Node(ensureWsdlUrl);
addJS_Node(allocCall);
addJS_Node(fnShowProgress);
addJS_Node(isSimpleType);
addJS_Node(isPrimitive);
addJS_Node(getSdl);
addJS_Node(processService);
addJS_Node(onImportLoaded);
addJS_Node(loadImports);
addJS_Node(invokeNext);
addJS_Node(callNext);
addJS_Node(getAttrib);
addJS_Node(getBaseName);
addJS_Node(getQualifier);
addJS_Node(getNextNsq);
addJS_Node(getUniqueNsq);
addJS_Node(parseSimpleType);
addJS_Node(parseType);
addJS_Node(parseArrayType);
addJS_Node(parseComplexType);
addJS_Node(parseAttrib);
addJS_Node(parseElem);
addJS_Node(parseSoapHeader);
addJS_Node(expBase);
addJS_Node(parseSchemas);
addJS_Node(parseSdl);
addJS_Node(ensureXmlHttp);
addJS_Node(encodeHeader);
addJS_Node(_invoke);
addJS_Node(callService);
addJS_Node(useService);
addJS_Node(getMsg);
addJS_Node(fixupDT);
addJS_Node(encTZ);
addJS_Node(encodePrimitive);
addJS_Node(bldJsAry);
addJS_Node(getNextIndexAry);
addJS_Node(vbArrayToJs);
addJS_Node(encodeArray);
addJS_Node(encodeVar);
addJS_Node(getArySize);
addJS_Node(get1stAryItem);
addJS_Node(getAryItemFromIndex);
addJS_Node(getSchema);
addJS_Node(getArySizeInfo);
addJS_Node(encodeAttrib);
addJS_Node(serPart);
addJS_Node(getWrap);
addJS_Node(encodeArgs);
addJS_Node(returnResult);
addJS_Node(decTZ);
addJS_Node(applyTZ);
addJS_Node(decDate);
addJS_Node(decTime);
addJS_Node(decodePrimitive);
addJS_Node(getAryInfo);
addJS_Node(decodeArray);
addJS_Node(decodeAryItem);
addJS_Node(getAryElem);
addJS_Node(decodeElem);
addJS_Node(decodeType);
addJS_Node(processResult);
addJS_Node(hideProgress);
addJS_Node(getResult);


function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
    var D                                   = document;
    var scriptNode                          = D.createElement ('script');
    if (runOnLoad) {
        scriptNode.addEventListener ("load", runOnLoad, false);
    }
    scriptNode.type                         = "text/javascript";
    if (text)       scriptNode.textContent  = text;
    if (s_URL)      scriptNode.src          = s_URL;
    if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';

    var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
    targ.appendChild (scriptNode);
}
like image 452
Ho1 Avatar asked May 05 '17 15:05

Ho1


2 Answers

Things to care

The site using xhr(async:false) in the HEAD request. Which is deprecated

You can read more about that here https://xhr.spec.whatwg.org/

The main statement is

Synchronous XMLHttpRequest outside of workers is in the process of being removed from the web platform as it has detrimental effects to the end user’s experience. (This is a long process that takes many years.) Developers must not pass false for the async argument when current global object is a Window object. User agents are strongly encouraged to warn about such usage in developer tools and may experiment with throwing an InvalidAccessError exception when it occurs.

So, change it to true.

Then use the @run-at document-end.

I created a script which do the job for you.

The approach I used,

Copied entire script code from the site and made necessary changes.

In user script, remove the script element and inject the changed script to web page.

It will alter the page as seen below. But it seems all the td elements are empty which came from the server.

enter image description here

You can see the network transfer here

enter image description here

This is the user script

// ==UserScript==
// @name        golestan
// @namespace   Sagar V
// @author      Sagar V
// @include     https://golestan.sbu.ac.ir/Forms/AuthenticateUser/login.htm
// @version     1
// @grant       none
// @run-at      document-end
// ==/UserScript==

(function(){
    var script=document.createElement('script');
    script.innerHTML=`c=0;
        Ip="/_Images/";ip="/_images/";tp="/_Templates/";scp="/_Scripts/";stp="/_styles/";Stp="/_Styles/";ap="/Forms/AuthenticateUser/";


        all   =new Array(
                         '/blank.htm',0,
                         scp+'printTemplate.htm?tck=r',0,
                         stp+'comm_butt2.htc',0,
                         stp+'select.htc',0,
                         stp+'simplegrid.htc',0,
                         stp+'validation.htc',0,
                         stp+'webservice.htc',0,
                         Stp+'helpStyle.css',0,
                         Stp+'winlessmovable.htc',0,
                         stp+'main.css',0,
                         stp+'MenuStyle.css',0,
                         stp+'Toolb.htc',0,
                         stp+'npui.css',0,

                         ap+'Message.XSLT',0,
                         ap+'Golestan.htm',0,
                         ap+'NewsPage.htm',0,
                         ap+'LoginPage.htm',0,
                         ap+'TopPage.htm',0,
                         ap+'main.htm',0,

                         tp+'Commander.htm',0,
                         tp+'Message_Page.htm',0,
                         tp+'help.htm',0,

                         scp+'Commander.js',0,
                         scp + 'npobj.js', 0,
                         scp + 'faci.js', 0,
                         scp+'Forms1_5.js',0,
                         scp+'help.js',0,
                         scp + 'Message.js', 0,
                         scp + 'npnfwin.js', 0,

                         '/_scripts/jqnpsrv.js', 0,
                         '/_scripts/npgrd.js', 0,
                         scp + 'Forms1_5_npgrid.js', 0,

                         Ip+'Status_OK.gif',0,
                         ip+'tabs.png',0,
                         ip+'ftabs.png',0,
                         ip+'corner.png',0,
                         ip+'c1.png',0,
                         ip+'jqnpgridicons.png',0,

                         '/Forms/F0202_PROCESS_REP_FILTER/command.htm',0);
        nall=0;
        for(k=0;k<all.length;k=k+2){
            if(all[k+1]==1)nall=nall+4;
            else nall++;
        }
        imstat=new Array('','_clicked','_focus','_disable');
        function check(){
            var x=new XMLHttpRequest() || new ActiveXObject("MSXML2.XMLHTTP");
            x.open("HEAD",document.location,true);
            x.send();
            var sd=new Date(x.getResponseHeader('Last-Modified'));
            var cd=new Date(document.lastModified);
            if(sd-cd>3660000){
                //alert('با توجه به تغييرات جديد سيستم ، جهت مشاهده کامل صفحات لطفا فايل هاي ذخيره شده در مرورگر خودرا حذف کنيد');
                document.cookie = "reloading=1";
                window.location.reload(true);
                return false;
            }
            return true;
        }
        function a(){
            for (k = 0; k < nall; k++) {
                td = document.createElement('TD');
                td.className = 'e';
                Pr.appendChild(td);
            }
            if (!check()) {
                //window.open("/_Templates/howtoclearcache.htm","_blank");
                //top.close();
                return;
            }
            var aCookie = document.cookie.split("; ");
            var cook=0;
            for (var i=0; i < aCookie.length; i++)
            {
                var aCrumb = aCookie[i].split("=");
                if ("reloading" == aCrumb[0]) {
                    cook=unescape(aCrumb[1]);
                    break;
                }
            }
            var ind=0;
            for( i=0;i<all.length;i=i+2){
                if(all[i+1]==1)
                    for(j=0;j<4;j++){
                        var r=new XMLHttpRequest() || new ActiveXObject("MSXML2.XMLHTTP");
                        r.open("GET", all[i]+imstat[j]+".gif", true);
                        if(cook==1) r.setRequestHeader('If-Modified-Since','Sat,01 Jan 2000 00:00:00 GMT');
                        getobj(r,ind++);
                    }
                else{
                    var r=new XMLHttpRequest() || new ActiveXObject("MSXML2.XMLHTTP");
                    r.open("GET", all[i], true);
                    if(cook==1) r.setRequestHeader('If-Modified-Since','Sat,01 Jan 2000 00:00:00 GMT');
                    getobj(r,ind++);
                }
            }
            document.cookie = "reloading=0; expires=Fri, 31 Dec 1999 23:59:59 GMT;";
        }


        function getobj(o,ind){
            o.onreadystatechange=function(){
                if(o.readystate==4){
                    Pr.cells(c).className="f";
                    c++;
                    if(c==nall){
                        if (location.search){
                            top.location = "main.htm" + location.search ; 
                         }
                        else
                    top.location="main.htm";
                    }
                }
            }
            o.send();
        }`;
    //alert(script);
    document.getElementsByTagName('script')[0].parentNode.removeChild(document.getElementsByTagName('script')[0]);
    document.head.appendChild(script);
})();

Or

Directly Install it from Github

like image 149
Sagar V Avatar answered Oct 21 '22 15:10

Sagar V


Sadly, a JavaScript-heavy web application built for IE is likely to have more IE-specific things within it than just making XMLHttpRequests. Using ActiveXObject to make XMLHttpRequests also means the JavaScript is written for a very old version of IE, because the standard XmlHttpRequest object has been present since IE7. So, expect the worst!

For the specific issue of making all calls to new ActiveXObject("MSXML.HttpRequest") work in Firefox. You can use the following in your Greasemonkey script:

window.ActiveXObject = function(type) {
  switch(type.toUpperCase()) {
    case "MSXML2.XMLHTTP":
    case "MICROSOFT.XMLHTTP":
      return new XMLHttpRequest();
      break;

    default:
      console.log("Unknown ActiveXObject type: ", type);
  }
}

I did test this with your given example, and I noticed that the JavaScript tests .readystate, not .readyState!

Further Greasemonkey patching can work around this:

Object.defineProperty(XMLHttpRequest.prototype, "readystate", {
    get: function() { return this.readyState; }
});

The next issue was that the JavaScript used the TableRow cells collection as if it was a function... Therefore:

Object.defineProperty(HTMLTableRowElement.prototype, "cells", {
  get: function() { return function(index) {
      return this.querySelectorAll('td')[index]; 
    };
  }
})

If it hadn't already felt like things are getting out of hand, the page completes and moves onto "main.html", where things get more interesting.

Because, it contains this very troublesome blast from the past:

<div id="service" style="display:none" style="behavior:url(/_styles/webservice.htc)"></div>

Microsoft CSS Behaviours!!! These were all the rage about 15 years ago or so.

If you thought getting to this point was bad, to go any further, would require more patience than I have the time for, I did take a look inside webservice.htc, and there's a whole lot of a reverse-engineering to script around that, for one Stack Overflow question.

I'm so sorry I couldn't get this to work for you!

Instead of investing time into that, I would personally resign myself to running IE on Linux through VirtualBox and use an IE VM

like image 30
Lee Kowalkowski Avatar answered Oct 21 '22 14:10

Lee Kowalkowski