J1.5

Difference between revisions of "Avoiding web browser same origin policy in Ajax applications"

From Joomla! Documentation

m (moving noinclude tags)
Line 50: Line 50:
  
 
Adding cookie and cache support is left as an exercise for the reader.
 
Adding cookie and cache support is left as an exercise for the reader.
<noinclude>[[Category:Development]]</noinclude>
+
<noinclude>[[Category:Development]]
[[Category:Tutorials]][[Category:Component Development]]
+
[[Category:Tutorials]][[Category:Component Development]]</noinclude>

Revision as of 09:31, 29 April 2013

The "J1.5" namespace is an archived namespace. This page contains information for a Joomla! version which is no longer supported. It exists only as a historical reference, it will not be improved and its content may be incomplete and/or contain broken links.

If you need to access a web service, using Ajax, that is running on a server that is not in your domain, then you will run up against the "same origin policy" [1] that will prevent you from retrieving data from outside your own domain for security reasons. There needs to be some way to circumvent this restriction on those occasions where the web service is trusted.

The most common method of circumventing the same origin policy in Ajax implementations is to access the remote web service via a proxy running in your domain. The proxy uses an HTTP client library (such as [2]) to access the remote server. This technique is usually simple enough, but can get tougher if the remote server requires authentication or uses cookies to track state between requests. On the plus side, using a proxy generally makes it easier to cache Ajax responses; something that is normally quite difficult.

To add a simple proxy to your Joomla component you simply need to add an extra task to the controller. The following code shows roughly what it might look like, given a static HTTP client class called httpClient with a method that will request a page from a remote server.

<?php
/**
 * Support cross-domain Ajax request by using the component as a proxy.
 * To use this facility replace "option" with "type" and "task" with "request"
 * in the query that would otherwise be sent to the remote server.
 */
function proxy()
{
	$uri = & JFactory::getURI();
	$query = $uri->getQuery( true );
	$query['option'] = $query['type'];
	unset( $query['type']);
	unset( $query['task']);
	if (isset( $query['request'] )) {
		$query['task'] = $query['request'];
		unset( $query['request']);
	}

	// Make the API call.
	$response = httpClient::call( $query );
	if ($response->status != '200') {
		JError::raiseError( 500, JText::_( 'Remote server error' ) );
		return false;
	}

	// And return the response.
	echo $response->data;
	jexit();
}

This example also shows how to work around the situation where the remote server is also running Joomla, in which case it will require a URL containing option and task arguments that may not match those required by the proxy. For example, suppose you want to make an Ajax request to a remote server using this URL:

http://www.remoteserver.com/index.php?option=com_remotecomponent&task=remotetask&arg=something

To avoid the same origin policy you send the request to the proxy instead using this URL:

http://www.localserver.com/index.php
     ?option=com_localcomponent
     &task=proxy&type=com_remotecomponent
     &request=remotetask
     &arg=something

You will need to adapt this code to meet your particular requirements, such as if you need to specify the controller in order to reach the proxy.

Adding cookie and cache support is left as an exercise for the reader.