A friend of mine asked me to build an AJAX shipping calculator for his e-commerce site. I accepted the project, thinking that his request would be easy to fulfill. I soon learned that his site was hosted by a third party e-commerce hosting company that does not (a) allow FTP access to his site and (b) process PHP or any other server-side scripting language. Using AJAX was going to be next to impossible. The reason it was going to be so hard is the same-origin policy.
The same-origin policy is incorporated into every major browser and prevents a script loaded from one site of origin from communicating with a document loaded from another site of origin.
I needed the shipping calculator to make a request to the R+L Carriers quote service, located at: http://www.rlcarriers.com/b2brateparam.asp. Same-origin policy says I can’t make a direct AJAX request (that will return a response) to any domain and port other than the one that the site content is on.
Normally circumventing the same-origin policy is a breeze, you just use a proxy on your domain to make the request. For example, you would use a URL like this in your AJAX request:
var url = '/proxy?url=' + encodeURIComponent('http://www.rlcarriers.com/b2brateparam.asp?weight1=1000')
See this Prototype JS documentation for further details.
I usually use a PHP proxy on my server to make requests to other domains. Unfortunately, my friend’s web host will not allow me to use a proxy script on my friend’s domain. But there is always a solution to every problem.
Turns out the <script> tag doesn’t care about same-origin policy. You can specify any domain you want in the ’src’ attribute of the script tag. My friend’s web host does allow me to put custom script tags into the checkout page.
Here’s kind of what it looks like:
<script src="http://www.foreigndomain.com/checkout.js" language="javascript"></script>
checkout.js has a function in it that runs code that looks like this, using the Prototype JavaScript library:
// Create the new script element and assign the a src attribute
var newScript = new Element('script', { 'src': 'http://www.foreigndomain.com/calculate-shipping.php?weight1=1000'});
// Put the new script into the page
document.body.appendChild(newScript);
When the function that contains this code is activated, a new script tag is created and added to the page on the fly. You can throw whatever variables from the current page into the parameters of your script tag src attribute. In the instance above I grab a zip code from the checkout page and pass it along with the weight. calculate-shipping.php, hosted on one of my domains, then makes the request to R+L Carriers and gets the shipping cost. All that is left is to have calculate-shipping.php echo out some JavaScript for the client to process. This is PHP echoing JavaScript:
// Process the shipping cost and put it into a variable called $shippingCharges
// Echo it out
echo "
$('shippingCharge').value = {$shippingCharges}; // This will update a form field on the checkout page with the estimated shipping cost
";
Turns out it the technique works like a charm. The purpose of all of the code above is just to explain the concept of using the <script> tag to circumvent the same-origin policy. The actual code that I am using has a lot more checks to make things a little more secure. You can check it out by visiting my friend’s e-commerce site at http://www.emergencymre.com/. Add something to your cart and go to the checkout page to see it in action.
Comments welcome!
Recent Comments