WNT 1.0

By Andrea Ercolino, 2009-10-04 20:38:50

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, "&lt;"); //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>

Leave a Reply

Panorama Theme by Themocracy