News

This week, I have been mostly getting JSONP

Written by DP | Oct 5, 2009 3:11:00 PM

I've just finished writing a test harness for a sms texting service. While writing this little tool I ran into a problem with cross site scripting issues.

Essentially its a form that is submitted to a page which then invokes methods to deal with the faked sms. It actually plays the part of the sms gateway host and saves me 50pence a shot!

The form submission is via AJAX, but because its on a different domain I get no success or useful error responses. This is where JSONP comes in.

As of jQuery 1.2 you can get JSON data from another domain if you add a JSONP callback and a little bit of handling on the server.

You also get the proper success and error responses.

The form looks a little like this:

<span style="color:#0000ff;">&lt;</span><span style="color:#800000;">form</span> <span style="color:#ff0000;">action</span><span  style="color:#333333;">=</span><span style="color:#0000ff;">"http://someOtherDomain/cross-site.php"</span> <span style="color:#ff0000;">method</span><span  style="color:#333333;">=</span><span style="color:#0000ff;">"get"</span><span style="color:#0000ff;">&gt;</span>
<span style="color:#000000;"> input1:</span><span style="color:#0000ff;">&lt;</span><span style="color:#800000;">input</span> <span style="color:#ff0000;">id</span><span  style="color:#333333;">=</span><span style="color:#0000ff;">"input1"</span> <span style="color:#ff0000;">name</span><span  style="color:#333333;">=</span><span style="color:#0000ff;">"input1"</span> <span style="color:#ff0000;">value</span><span  style="color:#333333;">=</span><span style="color:#0000ff;">"suits you sir"</span><span style="color:#0000ff;">/&gt;</span>
<span style="color:#0000ff;">&lt;/</span><span style="color:#800000;">form</span><span style="color:#0000ff;">&gt;</span>
<span style="color:#0000ff;">&lt;</span><span style="color:#800000;">button</span> <span style="color:#ff0000;">type</span><span  style="color:#333333;">=</span><span style="color:#0000ff;">"button"</span> <span style="color:#ff0000;">id</span><span  style="color:#333333;">=</span><span style="color:#0000ff;">"btnsubmitjson"</span><span style="color:#0000ff;">&gt;</span><span style="color:#000000;">jsonp submit</span><span style="color:#0000ff;">&lt;/</span><span style="color:#800000;">button</span><span style="color:#0000ff;">&gt;</span>
<span style="color:#0000ff;">&lt;</span><span style="color:#800000;">div</span> <span style="color:#ff0000;">id</span><span  style="color:#333333;">=</span><span style="color:#0000ff;">"response"</span><span style="color:#0000ff;">&gt;</span><span style="color:#0000ff;">&lt;/</span><span style="color:#800000;">div</span><span style="color:#0000ff;">&gt;</span>

The javascript that handles the button click event appends the JSON callback to the url and then submits the form with the power of jQuery:

<span style="color:#0000ff;">function</span> <span style="color:#000000;">submitjson(){</span>
   <span style="color:#000000;"> posturl = $("</span><span style="color:#8b0000;">form</span><span style="color:#000000;">").attr('action');</span>
    <span style="color:#000000;">posturl += "</span><span style="color:#8b0000;"><span style="color:#000000;">?</span>jsoncallback=?</span><span style="color:#000000;">"; </span><span style="color:#008000;">//append the JSON call back</span>
    <span style="color:#000000;">$.getJSON(posturl, $("</span><span style="color:#8b0000;">form</span><span style="color:#000000;">").serialize(),</span> <span style="color:#0000ff;">function</span><span style="color:#000000;">(data) {</span>
      <span style="color:#000000;">  $('#response').text(data.</span><span style="color:#0000ff;">name</span><span style="color:#000000;">);</span>
<span style="color:#000000;">    });</span>
<span style="color:#000000;">}</span>

And the final part (which is not so obvious) is the response required, generated by the server:

<span style="color:#0000ff;">&lt;?</span><span style="color:#000000;">php</span>
<span style="color:#000000;">$data = '</span><span style="color:#8b0000;">{"name" : "</span><span style="color:#000000;">'.$_GET['</span><span style="color:#8b0000;">input1</span><span style="color:#000000;">'].'</span><span style="color:#8b0000;">"}</span><span style="color:#000000;">';</span>
<a style="color: #0000ff" href="http://www.php.net/echo">echo</a> <span  style="color:#000000;">$_GET['</span><span style="color:#8b0000;">jsoncallback</span><span  style="color:#000000;">'].'</span><span style="color:#8b0000;">(</span><span  style="color:#000000;">'.$data.'</span><span style="color:#8b0000;">);</span><span  style="color:#000000;">';</span>
<span style="color:#0000ff;">?&gt;</span>

And its this last magic bit in the responding with $_GET['jsoncallback'] which makes it all work!

Now I can point my tool where ever I like, AND get the right responses (ah yeah).