WNT is a client side cross domain GET and POST plugin for jQuery based on window name transport. Look here for a short description of this technique on slide 36.
/*
* jQuery WNT plugin v1.0
* http://noteslog.com/wnt
*
* based on http://www.sitepen.com/blog/2008/07/22/windowname-transport/
* as explained in http://www.slideshare.net/mehmetakin/ajax-world
*
* Copyright (c) 2009 Andrea Ercolino
* Dual licensed under the MIT and GPL licenses.
* http://docs.jquery.com/License
*
* Date: 2009-10-04
*/
(function($) {
var container = 'body';
var isrc = "about:blank";
if ($.browser.opera) //tested in Opera 10
{
isrc = "javascript:''"; //this only works if opera's js debugger is active
isrc = "http://localhost/wnt/blank.html"; //this only works the first time after a refresh
isrc = "javascript:<html></html>;".replace(/</g, "<"); //this works
}
function parseParams(url)
{
var result = [];
url.replace(/[?&]([^=]+)=([^&#]*)/g, function( param, name, value ) {
result.push( '"' + name + '"' + ':' + '"' + value + '"' );
});
result = '({' + result.join(',') + '})';
result = eval(result);
return result;
}
function addForm(action, target, method, data)
{
var form_html = ''
+'<form'
+' action="'+ action +'"'
+' target="'+ target +'"'
+' method="'+ method +'"'
+' style="display: none;"'
+'></form>'
var $form = $(form_html).appendTo(container);
var params = 'GET' == method ? parseParams(action) : {};
data = $.extend(params, data);
$.each(data, function(name, value) {
$('<input type="hidden" name="'+ name +'" value"">')
.appendTo($form)
.val(value)
;
});
return $form;
}
function addIframe(name, src)
{
var iframe_html = ''
+'<iframe'
+' name="'+ name +'"'
+' src="' + src +'"'
+' style="display: none;"'
+'></iframe>'
;
var $iframe = $(iframe_html).appendTo(container);
return $iframe;
}
function handle_request(method, url, data, handle_response)
{
var iname = 'iframe' + (new Date).getTime();
var $iframe = addIframe(iname, isrc);
$iframe
.data('back', false)
.bind('load', function() {
if ($iframe.data('back'))
{
var response = $iframe[0].contentWindow.name;
if ($.isFunction(handle_response))
{
handle_response(response);
}
$form.empty().remove();
$iframe.empty().remove();
}
else
{
$iframe.data('back', true);
$iframe[0].contentWindow.location = isrc;
}
})
;
var $form = addForm(url, iname, method, data);
$form[0].submit();
}
$.extend({
wnt: {
'get': function (url, data, callback) {
handle_request('GET', url, data || {}, callback);
},
'post': function (url, data, callback) {
handle_request('POST', url, data || {}, callback);
}
}
});
})(jQuery);
Example
This is hello-service.php. It’s a remote service that can be accessed by means of a get or post request. Its response is in JSON format, but you can use whatever you like.
<?php
try
{
switch ($_SERVER['REQUEST_METHOD'])
{
case 'GET':
$name = $_GET['name'];
break;
case 'POST':
$name = $_POST['name'];
break;
default:
throw new Exception('request method not supported');
break;
}
$name = addslashes($name);
$result = "<p>Hello $name!</p>";
$status = 200;
}
catch (Exception $e)
{
$result = $e->getMessage();
$status = 500;
}
$response = json_encode(array(
'status' => $status,
'result' => $result,
));
?>
<html>
<head>
<script type="text/javascript">
window.name='<?php echo $response; ?>';
</script>
</head>
<body>
</body>
</html>
This is test-jquery-wnt.html. It’s a web page that accesses the hello service by means of a get or post request. Due to the fact that the response is in JSON format, it includes json2 for parsing.
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="json2.min.js"></script>
<script type="text/javascript" src="jquery-wnt.js"></script>
<script type="text/javascript">
var service_url = "http://noteslog.com/personal/projects/wnt/hello-service.php";
function display_response( data )
{
try
{
var response = JSON.parse( data );
}
catch (e)
{
response = {status: 500, result: e}; //please forgive naïve error control
}
if (response.status == 200)
{
$('#result').html(unescape(response.result));
}
else
{
$('#result').html('<span style="color: red;">'+ response.result +'</span>');
}
}
</script>
</head>
<body>
<p>
What's your name? <input type="text" name="name" value="" id="name" />
<a href="#" onclick="$.wnt.get(service_url, {name: escape($('#name').val()) || 'mystery guest'}, display_response);">get</a>
|
<a href="#" onclick="$.wnt.post(service_url, {name: escape($('#name').val()) || 'Nobody'}, display_response);">post</a>
</p>
<p>
Wellcome. This is a simple test page for WNT 1.0<br>
Using WNT, this page talks to a remote hello service that simply greets back with data
received in a GET or POST request.<br>
The hello service is hosted at http://noteslog.com/personal/projects/wnt/hello-service.php,
so you have to run this test page from a different domain, like your localhost (if you run
an http server locally), to test the cross domain capabilities of this jQuery plugin.
</p>
<p>
<div id="result" style="background: #EFEFEF;"></div>
</p>
</body>
</html>
In the referenced, article, they mention:
“Consequently, the windowName module uses a set of three nested frames, where 1st frame blocks all frame traversal to the 2nd frame using dynamically installed getters that return null. This means that third party frames can never traverse the frames to get a reference to the 2nd or 3rd frames, and consequently can never induce navigation of the target frame (the 3rd frame) in order to access the name property.”
Is this also accounted for in the WNT 1.0 plugin? My experience with JQuery is pretty limited, but as far as I could tell, there was only 1 iframe being added with the addIframe() function. Thanks -Andy