Using JSONP for cross-host "Ajax" calls with jQuery

When trying to make cross-host Ajax calls, you’ll likely run foul of the browser’s “same origin policy”. Usually, the user will be presented with a pop-up similar to this:

This page is accessing information that is not under its control.

One solution is JSONP. It happens that the same origin policy is relaxed for certain tags and that includes the <script> tag. JSONP takes advantage of this by writing a <script> tag to the document (instead of using the XMLHttpRequest object of traditional Ajax). The src attribute of the script tag specifies the Ajax URL. Instead of the traditional HTML response, the server returns JavaScript; more specifically, a JSON object wrapped in a function call. In many implementations, the JSON simply encapsulates a HTML fragment and the called function loads it somewhere in the document.

Obviously, due to the nature of JSONP, POST requests are not available.

jQuery makes implementing the client-side of JSONP straightforward through the ajax() method. Here’s an example (assume “host1” is hosting the page and “host2” is serving Ajax requests):

$.ajax({
  url: ‘http://host2/GetJSON’,
  dataType: ‘jsonp’,
  success: function(data) {
    $(‘#content’).html(data.html);
  }
});

jQuery will append a call-back method name to the query-string of the URL: http://host2/GetJSON?callback=jsonp1265718231899

It is the responsibility of the server-side code to output JavaScript that calls the method supplied in the query-string. So, given the above request, host2 would return JavaScript that looks like this:

jsonp1265718231899({ html: "<h1>HTML Fragment</h1>" });

The JSON object ({ html: "<h1>HTML Fragment</h1>" }) is passed to the success call-back. In this particular example the success call-back simply updates the document with the value of the html property.

jQuery is a powerful JavaScript library with all kinds of useful functionality in addition to Ajax support. If you haven’t tried it already, I recommend you do. You won’t look back.

Comments off

Copying the contents of a hard disk drive and an opportunity to revisit Linux

My current 80GB HDD was running low on disk space and so it was time for an upgrade. My plan was to copy the data from the old HDD to a new 500GB one and extend the one and only system partition. A straightforward task.

Now, the PC in question has only one SATA port on the motherboard so that ruled out a straight disk-to-disk copy, complicating things slightly. I decided to copy the existing data to a Windows fileserver on my local network, install the new disk and copy it back. Using an external USB hard disk would’ve been a viable alternative.

I don’t know how to do a straight sector copy in Windows without resorting to third-party software or writing code, so I decided this would be a good opportunity to try a Linux-based “Live CD”. I chose Ubuntu simply because it was the first that came to mind and I knew it would have almost all the utilities that I needed right there on the CD.

First impressions… everything just works. Booting from the Ubuntu CD, after a minute or so I’m looking at the GNOME desktop. Wireless networking is working; video is working; impressive!

To mount the SMB share on my Win fileserver, I needed to grab smbfs …

sudo apt-get install smbfs

… and mount the share:

smbmount \\\\myserver\\myshare ./images –o user=myuser

I piped the existing HDD data through gzip to save on storage and network bandwidth:

sudo dd if=/dev/sda bs=512 | gzip > ./images/sda.img.gz

After a few hours of network copying, I swapped out the old HDD for the new and copied the data back:

gzip –c -d ./images/sda.img.gz | sudo dd of=/dev/sda bs=512

Note: I copied every sector including the MBR / partition table from the old to the new disk. This approach will only work if both disks have the same geometries.

dd responds to the USR1 signal by writing status to stderr, so I tracked progress (updating every 2 minutes) during long running dd operations using:

sudo watch –n 120 killall –s USR1 dd

I then used GParted to take care of resizing the NTFS partition to occupy the entire disk.

After a reboot into Win XP and one chkdsk later, I had more than 400GB free disk space.

Disclaimer: I don’t recommend you follow this approach unless you’ve backed up your data, are prepared for the possibility that things may turn bad and have a reasonable idea of what you’re doing.

Comments off

Tree traversal, LINQ style

When dealing with tree structures, it’s helpful to be able to visit all nodes. Here’s an extension method that makes traversing tree structures easier (in this case, in preorder, depth-first).

internal static class TreeTraverse
{
    public static IEnumerable<T> PreorderTraverse<T>(this T node, Func<T, IEnumerable<T>> childrenFor)
    {
        yield return node;

        var childNodes = childrenFor(node);
        if (childNodes != null)
        {
            foreach (var childNode in childNodes.SelectMany(n => n.PreorderTraverse(childrenFor)))
            {
                yield return childNode;
            }
        }
    }
}

This extension method allows you to treat any type as the root node of a tree, providing you can define a sensible childrenFor method for it.

Example usage:

var root = new Node
{
    Name = "root",
    Children = new List<Node>()
    {
        new Node
        {
            Name = "root > child A",
            Children = new List<Node>()
            {
                new Node
                {
                    Name = "root > child A > child AA"
                }
            }
        },
        new Node
        {
            Name = "root > child B"
        }
    }
};

foreach (var node in root.PreorderTraverse(n => n.Children))
{
    Console.WriteLine(node.Name);
}

Where Node is defined as:

class Node
{
    public string Name { get; set; }
    public IEnumerable<Node> Children { get; set; }
}

To use PreorderTraverse on an IEnumerable<T> you can combine with SelectMany, as in fact the PreorderTraverse extension method does.

Comments off

Unknown PCI device (Device Manager) – How can I find out what drivers I need?

If a PCI device is showing up as an “Unknown Device” in the Windows Device Manager (devmgmt.msc) and you’re not sure what the manufacturer and/or device name is, here’s a quick tip that may help.

Pull up the Properties for the device. Select “Hardware Ids” in the drop-down and make a note of the Vendor (VEN_XXXX) and Device (DEV_XXXX) identifiers (in this example, 8086 and 24C6). With this information you can search for your device at http://www.pcidatabase.com/.

DeviceProperties 

Once you have the vendor and device name, it will increase your chances of finding the correct driver on the manufacturer’s website.

Comments off

C# Anonymous functions for conditional operations

More specifically, lambda expressions… Let’s say you have a method, the body of which will execute based on the value of a flag (myFlag in the example here):

public void MyConditionalMethod(string format, params object[] args)
{
    if (myFlag)
    {
        DoSomething(string.Format(format, args));
    }
}

Ideally, in scenarios where myFlag is false we’d like a call to this method, such as the following, to have limited overhead:

MyConditionalMethod("{0}, {1}", param0, param1);

If param0 and/or param1 are value-types, this call will incur the overhead of boxing regardless of the value of myFlag. Obviously, things get worse as we pass more value-types as parameters.

One approach to addressing this problem is through the use of lambda expressions; the lambda expression is only executed if the flag is set. Here’s a version of MyConditionalMethod modified accordingly:

public void MyConditionalMethod(Func<string> getString)
{
    if (myFlag)
    {
        DoSomething(getString());
    }
}

A call to the modified method looks like this:

MyConditionalMethod(() => string.Format("{0}, {1}", param0, param1));

 

Here are some rough performance numbers (with compiler optimizations on) to illustrate the potential advantages of this approach:

  Min (ns) Max (ns) Median (ns)
Standard (1000 iterations, 10 samples) 74.396 434.688 147.888
with lambda (1000 iterations, 10 samples) 5.692 11.687 5.692

 

This technique can be used in tracing or other scenarios where these methods may be called frequently throughout your code and it can have a significant performance benefit in the aggregate.

Comments off

« Previous Page« Previous entries « Previous Page · Next Page » Next entries »Next Page »