shake, with fries

by Zach Carter

Posts tagged json

Dec31

Orderly.js Web Version

javascript json jsonschema orderly | comments

I've commited a minified, dependency-free version* of orderly.js for use on the web. It introduces an orderly object, with parse and compile methods.

Usage is straight forward:

<script src="orderly.js"></script>
<script>
    var orderlySource = "array {};";

    var jsonSchemaSource = orderly.compile(orderlySource);

    var jsonSchemaObject = orderly.parse(orderlySource);
</script>

Edit: View the online demo here.

*Excpet for a JSON stringifier, to account for browsers that don't include native JSON yet.

Dec27

Orderly.js: Orderly to JSONSchema Compiler

javascript commonjs jison orderly jsonschema json compiler parser | comments

Orderly is a textual format for describing JSON. Orderly can be compiled into JSONSchema. It is designed to be easy to read and write.

I decided to give Jison a real-world spin by creating an Orderly to JSONSchema compiler for JavaScript. After about three days, interspersed with lots of eating and family vists, I have a working implementation, which I call Orderly.js.

Usage

var orderly = require("orderly");

var orderlySource = "array {};";

var jsonSchemaSource = orderly.compile(orderlySource);

var jsonSchemaObject = orderly.parse(orderlySource);

print(JSON.stringify(jsonSchemaObject));

An API for building parsers

I must say, Jison made this really simple. I don't consider myself a speedy coder in the slightest, probably the opposite, but I was able to crank this out in a (holiday) weekend. Jison takes care of the hard parts of parsing, all you need is a working grammar* and the appropriate hooks. I'll be writing more on Jison shortly.

*This can be non-trivial, though if the language you are parsing already specifies a grammar, as was the case with Orderly, you're set!

Jul03

Cross-site HTTP Request for jsonip

json javascript html5 jsonp ajax | comments

I've added cross-site HTTP request support for jsonip, a micro-service I introduced previously that retrieves a client's IP address. Now, with HTTP access controls and a browser that supports them (such as Firefox 3.5,) any site can use a regular XmlHTTPRequest to utilize the service instead of JSONP. This might not be terribly useful today, as most browsers don't support HTTP access controls, but the arrival of Firefox 3.5 beacons the future of possibilities.

Here's a new cross-site HTTP request usage example:

<script>
  var req = new XMLHttpRequest();  
  req.open('GET', 'http://jsonip.appspot.com', true);  
  req.onreadystatechange = function (e) {  
    if (req.readyState === 4) {  
      if(req.status === 200) { 
        var ip = JSON.parse(req.responseText); 
        alert(ip.address);
      } else {  
        alert("Error loading page\n");  
      }
    }  
  };  
  req.send(null); 
</script>

You'll notice it looks just like a regular XmlHTTPRequest, except the domain does not have to be your own. My service at jsonip.appspot.com is using special headers that allow this to work instead of greeting you with the usual permission errors.

The source code of the python script I use for the service is below. You'll notice where the special headers are added:

import os
import cgi

form = cgi.FieldStorage()
callback = form.getvalue('callback','')

address = cgi.escape(os.environ["REMOTE_ADDR"])

json = '{"ip": "'+address+'", "address":"'+address+'"}'

#Allow cross domain XHR
print 'Access-Control-Allow-Origin: *'
print 'Access-Control-Allow-Methods: GET'

if callback != '':
  print 'Content-Type: application/javascript'
  result = callback+'('+json+');'
else:
  print 'Content-Type: application/json'
  result = json

print ''
print result

The magic happens here, with these printed headers:

print 'Access-Control-Allow-Origin: *'
print 'Access-Control-Allow-Methods: GET'

The first header means any domain can use this service cross-domain. Alternatively, you could have a comma seperated list of domains instead of a * to allow requests only from those domains. I want my service open to all sites, so I use a *.

The second header is self-explanatory (as if the first wasn't:) there's no need to support any other HTTP methods for this simple service, so I limit them to GET.

There are more access control headers available, so do make sure to read the article before trying these out. Some configurations could be dangerous, depending on your service.

Other jsonip Changes

  • JSON output uses double quotes for property names, as per the JSON specification
  • Added address property to use instead of the old ip property to retrieve the IP address. I've left the ip property for backwards compatibility.

The old, JSONP method of use still works as expected:

<script>
// callback function
function getip(jsonip){
  alert(jsonip.address) // alerts the ip address
}
</script>
<script type="text/javascript" src="http://jsonip.appspot.com/?callback=getip"> </script>

Sep22

jsonip, retrieve the client's IP address via JSONP

javascript json | comments

This question on Stackoverflow spurred me to write my first Google App Engine project and consequently my first Python script, jsonip. It lets you retrieve a client's IP address without needing your own server-side script. Normally you could make a call to a local server script that prints the user's IP address then use an XMLHttpRequest to retrieve it. jsonip uses JSONP, so you could use it in a situation where you don't have server-side processing available. The usage is simple enough:

Here's the source code for the Python script: (When I say this was my first Python script, I mean it! I had to ask Google how to write if..then statements... )