Making JSONp, jQuery and RESTful urls work

How to use RESTful urls with JSONp including jQuery example

Following up on the previous post from Making cross domain JSON work with jQuery and RESTful urls, I was left with a solution that wouldn’t work for me. After a little more searching I found a JSONp library on google code that allows the user to specify a request url explicitly without any kind of automatic url generation. To me, this implied the capacity to support REST and fortunately it does.

I’ll start with the syntax for the call using the jsonp plugin (note I’m not using jsonp to construct the url):

url = "http://otherdomain.com/getMyFavoriteImage";
url += "/tag_marine";
url += "/format_json";
url += "/callback_myFunction";

$.jsonp({
  "url" : url,
  callback : "myFunction",
  cache : "false",
  success:function(data){
    $("<img alt="" />").attr("src", data.imageurl).appendTo("#images");
  }
});

After modifying my web service, I was able to receive the following response based on this request:

myFunction({
  imageurl: 'http://test.com/focktopus.jpg',
  description: "1 legged octopus"
});

You can read the rest of JSONp’s API on their google code page, but there are two parameters that were critical for me.

  • callback – This is the name of the callback function that will be expected from the web-service response. It can be called anything (_jqjsp is the default callback name)
  • cache – I needed to set this to false because I didn’t want a cache buster appended to the end of my urls. This is set to true by default and would mess up my edge cacheing (I want to manage that from the cms)

How the callback works

I wanted to assemble the url myself based on my variable structure (which JSONp allows you to do since the url is just an unmodified argument). If you’ll notice I’m passing in a callback name of “myFunction” in my url by passing in the argument callback_myFunction. The “callback_” designates this variable as the name of the function to wrap the response in to my web-service. Some web-services that support JSONp do not allow you to customize the name of the callback function in their response. In these cases you would just specify the expected function as the callback parameter.

I’ll follow up with a post soon on the webservice itself.

Posted in Uncategorized | Leave a comment

Making cross domain JSON work with jQuery

It’s not possible to pull raw JSON cross domain using JQuery.getJSON. This is possible in flash, but not in the browser because of limitations browsers place on XMLHttpRequest. You will see the data coming back in your http sniffers, but it will never make it to javascript and it can be a frustrating problem to diagnose if this is new to you.

Standard JSON request (same domain)

A standard JSON request in jQuery might look like the following (If the request is coming from the same domain as the webservice:

$.getJSON(
  "http://mydomain.com/getMyFavoriteImage",
  {
    tags: "marine",
    format: "json"
  },
  function(data){
    $("<img/>").attr("src", data.imageurl).appendTo("#images");
  });

The response might look like the following and will be available to javascript if the requesting domain matches the webservice domain.

{
  imageurl: 'http://test.com/focktopus.jpg',
  description: "1 legged octopus"
}

If you try this on another domain, you will probably notice this response showing up in Charles or firebug, but your listeners will not trigger and you won’t be able to access your data. Flash handles the response without an issue and it was the success in flash that led me to waste a lot of time troubleshooting in the browser.

Enter JSONp, which is basically JSON, but wrapped in a callback function. The idea behind JSONp is basically to return a small javascript function with the JSON response as an argument. If you specify the callback in advance, jQuery will dynamically insert a function with the expected callback name in the head of the document at the time the request is created, otherwise it will generate a callback name automatically. This function will receive the JSON and route this information back to your request listeners. This will, of course, require that the webservice have the capacity to wrap the JSON in this function, otherwise you will have to use a server side proxy to return the result. Ideally the webservice would also be set up to receive the name of the callback as an argument, otherwise it will use a standard function name and then wrap the JSON response in the function name. I’ll show what this looks like in a minute.

It didn’t take long to find detailed information on JSONp solutions, which will work across different domains and will look the same as the original request with the exception of the external domain name and the “?callback=” appended to the url:

$.getJSON(
  "http://notmydomain.com/getMyFavoriteImage?callback=",
  {
    tags: "marine",
    format: "json"
  },
  function(data){
    $("<img/>").attr("src", data.imageurl).appendTo("#images");
  });

JQuery will detect the presence of the callback variable and modify the request with a unique function name before sending it out. The webservice will need to parse out this parameter and wrap the JSON in this function name as in the example shown below:

jQuery1604525964497588575_1304697924228({
  imageurl: 'http://test.com/focktopus.jpg',
  description: "1 legged octopus"
});

Because this is a script, it is not subject to the same restrictions as a JSON payload and can be received by the browser without issue.

jQuery’s JSONp solution will not work with REST

The framework I am using is bound to REST, so query strings were off the table. JQuery.getJSON() supports JSONp but requires the “?callback=” to be appended to the URL and these values were simply not available to me, but it’s important to note this is the general solution. I’ll continue the solution in Part 2: Making JSONp, jQuery and RESTful urls work

Posted in Uncategorized | Leave a comment

Function for turning XMLList into an object

When exploring using XML as a description language for externally loaded swfs, I found it easier if I just placed a recursive
function in the code to turn the XML node into an object. Most of the time I had the luxury of JSON available to me, but in some cases I had to work with XML and I found this function worked pretty well for the most part.

private function getObject(xml:XMLList):Object{
	var length:Number			=	xml.children().length();
	var object:Object			=	new Object();
	var data:XML;
	for ( var i:Number = 0; i < length; i++ ){
		 data = xml.children()[i];
		if(data.children().length() == 1 && !xml.children()[i].hasComplexContent())
			object[data.name()]	=	String(data);
		else 
			object[data.name()]  =  Object(getObject(XMLList(data)));
	}
	return object;
}

This is a recursive function that copies simple tags and their values into an object. I might revisit this function to include attributes at some point in the future. There is also a data typing problem that I need to resolve where the nodes are typed as XML rather than strings.

Posted in Uncategorized | Leave a comment

PHP exec function with SVN

Spent the day trying to figure out how to export a folder from SVN to a folder on my server. First I found that tortoiseSVN doesn’t support command line, so I found slickSVN which has a command line alternative. This was my foray into Command line svn use, so I had to do a bit of searching for svn commands and how to use them, etc. Once I found these I started out creating a batch file to see what I could get working.

I settled on the following:

svn export http://svn.mydomain.com/myFolder D:\myOpsFolder\ --force

and all seemed to be working well from the batch file, but when I tried to execute this batch file from php it would time out. After a lot of beating my head against the wall as to why php’s exec was not working for svn, I realized that it was using the apache user credentials which probably did not have access to my windows login and its credentials. I included the user / password parameters as follows and I was able to call the batch file from php:

svn export http://svn.mydomain.com/myFolder D:\myOpsFolder\ 
            --username user --password PASS --force

The php for calling the batch file looked something like this:

exec("cmd /c D:\workspaces\PHP\myProject\src\ops\default\cron\svnUpdate.bat");

from there I started working on making the call directly from PHP so I could work some user variables into the Mercularity CMS. As of this writing, I am using the following code and it seems to be working fine.

		$command		= "svn export";
		$repositoryURL	= "http://flash.svn.mysite.com/myfolder";
		$localFolder	= "D:\workspaces\PHP\myproject/myassets";
		$svnUserName	= "myUser";
		$svnPassword	= "Pass";
		
		$svnParams		= Array();
		array_push($svnParams, $command);
		array_push($svnParams, $repositoryURL);
		array_push($svnParams, $localFolder);
		array_push($svnParams, "--username " . $svnUserName);
		array_push($svnParams, "--password " . $svnPassword);
		array_push($svnParams, "--force");
		$cmd = join(" ", $svnParams);
		exec($cmd);

Not really sure why the “–force” param is needed as I couldn’t find an explanation of that parameter, but the calls didn’t seem to work without it (it might be because I didn’t specify a revision). If anyone knows what this is for, please feel free to comment.

Posted in PHP | Tagged , | Leave a comment

Control bar part one, insertion cursors and remaining space

Control bars are there to allow control and provide status representation of the active video content. Because the content can change, so can the needs of the control bar. A live program using a DVR window for instance, would not require a scrubber with a buffer, nor would it require an elapsed time or a duration label since the video is a continuous stream, but the DVR window does require some kind of time marker representation as well as a some kind of scrubber navigation control to change the dvr point.

Here are a few examples of different control bars for different circumstances:

The Challenge is to create a control bar that can easily identify its width and to add components to the left and right while allowing for variable sized components dynamic scrubber bar sizing and positioning. To do this, we can start with some simple variables:

	private var _displayArea:Rectangle;
	private var _remainingSpace:Number;
	private var _leftCursor:Number;
	private var _rightCursor:Number;

These variables give us the following bits of information.

  • _displayArea is where we can store the current size and position information of the control bar.
  • _remainingSpace holds the amount of width left for the creation of dynamically sized elements such as the scrubber bar
  • _leftCursor is the insertional x position where the next left element will be added
  • _rightCursor is the insertional x position where the next right element will be added

Inserting a control

When the control bar is initialized, the padding is added to the left cursor and the right cursor is set to the width of the control bar. When a component is added to the control bar calling addFromLeft, the following happens:

	public function addFromLeft(element:DisplayObject, padding:Number = 0):void{
		element.x		= _leftCursor;
		_leftCursor		= _leftCursor + element.Width + padding;
		_remainingSpace -=  element.Width - padding;
	}

	public function addFromRight(element:DisplayObject, padding:Number = 0):void{
		element.x		= _rightCursor - element.width;
		_rightCursor	= _rightCursor + element.Width + padding;
		_remainingSpace -=  element.Width - padding;
	}

Following this logic, we can add control elements to the left and right of the control bar, while maintaining a variable to hold the size of the scrubber bar.  This will allow for the effect below:

This movie requires Flash Player 9

Next we are going to need to create some vectors to hold the control bar buttons.  Without getting into the contents of this class yet, I’m going to use an interface called IControlBarElement to represent the control bar elements that extends movieclip.  I’ll get into why in later segments of this tutorial, but for now I’m going to create four vectors:

protected var _scrubber					:IControlBarElement;
protected var _outterLeftElements		:Vector.;
protected var _outterRightElements		:Vector.;
protected var _innerLeftElements		:Vector.;
protected var _innerRightElements		:Vector.;
Posted in Uncategorized | Leave a comment