Monday 30 November 2009

Changing all links and source attributes in the DOM

Working with hosted merchant payment solutions

If you have ever worked with hosted payment solutions such as SecPay (now PayPoint) and WorldPay you will have dealt with Callback pages which are pages containing server-side code e.g .NET, ASP, PHP etc and located on your webserver but are loaded up and displayed within the payment gateways secure domain.

This means that any relative links on images, stylesheets, scripts and anchors will be relative to the payment gateways domain and not your webserver. Therefore if you don't apply some code to correct these links the styles won't load and the links won't go anywhere apart from 404 error pages.

You could ensure that all your links are absolute anyway in which case you won't have a problem but often this isn't possible for numerous reasons. Therefore if you don't want to create a very basic minimal template page to use for your callback page to get round this issue you can use some client side Javascript to loop through all the relevant collections and change the links to reflect the true location of the files.

The following function is one that I use on my own system. It is called once the page loads and loops through the A, LINK, SCRIPT and IMG collections checking the current src or href attributes and makes sure any relative links are changed into absolute ones pointing to the true base URL (e.g your site) and not the payment gateway, and for absolute links that have already been resolved incorrectly it replaces the payments domain with the true domain. This ensures that all links point to absolute URI's that reference your site and not the payment gateway which has loaded the content to display on its own system.

If you are using server side code in your callback page then you can replace the top two parameters makeAbs.domain and makeAbs.directory that refer to the base URL and the Virtual directory that contains the callback page on your webserver with some code to dynamically populate those values. The full function code is below.
makeAbs = {
// the domain we want to reference
domain : "http://www.mysite.com",

// the virtual directory containing the file that will be referenced
directory : "/somedomain/subdomain/",

// function to modify the DOM call once page has loaded
ModifyDOM : function(){

// change Anchors
this.ChangeLocation("A","href");

// change CSS Links
this.ChangeLocation("LINK","href");

// change SCRIPT
this.ChangeLocation("SCRIPT","src");

// change IMG
this.ChangeLocation("IMG","src");

},

ChangeLocation : function(tag,att){

var o,n,h,e=document.getElementsByTagName(tag);
for(var i=0,l=e.length;i<l;i++){
o = (att=="href")?e[i].href:e[i].src;

// if current href/src is blank then skip
if(o && o!=""){

// if its a relative link
if(!/^https?:\/\//.test(o)){

// if its just a filename then we need the domain + virtual to create absolute URL otherwise just need our domain
n = ((o.substring(0,1)=="/") ? this.domain : this.domain + this.directory) + o;

// if its an absolute URL make sure the payment servers domain is replaced with our own in case relative links
// have already been associated with the wrong location
}else{
n = o.replace(document.location.protocol + "//" + document.domain,this.domain);
}

// now reset with our new value
if(att=="href"){
e[i].href = n
}else{
e[i].src = n;
}
}
}

}
}


The code can be downloaded as a file from the following location: makeAbsolute.js

No comments: