» tagged pages
» logout

sorted by: recent | see : popular
Content Tagged with User:alex + Development

Timeframe

open source datepicker

User:alex: My Bookmarks

Dojo Shrinksafe

javascript shrinker

User:alex: My Bookmarks

How To Provide A Web API

In a world where people are making interdependent webservices, API design and maintenance is pretty important. Unfortunately despite rising use and availability of APIs, there are significant problems with the way even big API vendors are deploying and maintaining their APIs.

What are a few simple rules for providing a web API?

  1. Keep it clean and simple
  2. Stick to standards
  3. Make it about data
  4. Keep it working
  5. Design for updates

Keeping it clean and simple is subjective and a matter of audience. For most developers a simple API is REST/HTTP based, with XML delivery of a known or simple schema, RSS being a good general choice. For JavaScript developers or plugin writers JSON feeds might be preferrable. For enterprise development scenarios, SOAP over HTTP might be better, but generally it’s best to stick with just REST + XML/RSS.

Simple also means don’t be too abstract. Flickr for example chooses in its API to require the use of its internal ids for all API calls. This means for example that every call to find information about a user requires a call first to find the internal id of the user. Del.icio.us on the other hand just requires visible names, in fact internal ids are hidden everywhere.

Sticking to standards is a matter of developing APIs that can plug in to accepted norms. Not only does this make development easier, it makes tooling and other peripheral services work better, and generally standards are written for a good reason. Using REST? Don’t use GET requests to update state, such as in del.icio.us’s urls to delete or add urls like https://api.del.icio.us/v1/posts/add?. Using RSS? Try to stick to mainstream semantically appropriate elements rather than new namespaces, provide well formed XML, don’t stick data in XML attributes, etc.

Make it about data. Leave application design to the application developer. Google’s new Ajax search results API is a good example of an API that isn’t about data, which makes less flexible to build upon. Instead of providing JSON feeds for plugin developers, Google has chosen to build out their own little search results box, with controls and results that cannot be styled, instead of leaving the interface and logic up to the Javascript developer or plugin writer. A better design would have been a simple JSON feed of Google service search results, and a reference object to build an embedded results box.

Keep it working. An application developer working with remote web services should design with the consideration that the remote service can malfunction or die, but that doesnt’ mean that service providers shouldn’t prioritize keeping reliable service high on their list. On SWiK and other development projects I’ve done, every one of the APIs we use (del.icio.us, sourceforge, google, etc) have gone down or had problems, and I learned the hard way not to depend on any of them.

Make a clean upgrade path. There’s no permanent APIs: add a version number and keep developers informed. Flickr calls don’t have a version number but they should. In del.icio.us even browser bookmarklets have versions. Salesforce.com, whose bottom line depends on web service APIs, uses versioned WSDLs. Each new rev of Salesforce.com’s APIs are given a unique WSDL and the backend from that point is kept stable once the WSDL has been issued. This has come into practice because just like native APIs, customers started to build code against buggy behavior, and when the server logic was updated to fix bugs, their code broke. Now if there’s broken code it stays in place, and developers migrate to new services at regular and scheduled intervals.

Recently del.icio.us updated their post API to use a secure encrypted URL, so as not to betray passwords or bookmarks in cleartext if they were posted using the API. A good move, especially as developers are using GET requests to post bookmarks, which may be prompting some routers to cache sensitive user data. Yahoo was nice enough to provide clear documentation and plenty of warning about the change though. After a few months of warning, the old insecure URL was turned off, and legacy requests are redirected to the secure URL, all in all a very good update.

On the other hand, del.icio.us recently updated their rss feed of recent bookmarks: http://del.icio.us/rss to be a bit more ‘digg-esque’. Instead of showing the steady stream of users adding bookmarks to their accounts, it now aggregates the popular urls, showing you something that is currently being bookmarked quite a bit. Well guess what? LiveMarks uses those front page rss feeds to aggregate del.icio.us bookmarking activity. The RSS feed change, which was completely unannounced, significantly impacted that application, and I wish they had given some warning that the URL was going to change, instead of silently changing it. (If you are hosting a mirror for LiveMarks and I haven’t contacted you, please change the aggregation url to http://del.icio.us/rss/recent instead of http://del.icio.us/rss/).

As a sidenote, a personal annoyance is the reluctance of service providers to provide APIs against what they consider to be their most important property: public user data.

Even though many times the data is made public in various forms, such as through RSS feeds or HTML pages, data like my favorites on Flickr or my older bookmarks on del.icio.us require authorization to access, which means as a developer the interface and code needs to be more complicated to use these APIs. The new Google Ajax Search API for example requires a separate API key I must apply for, I can’t use the Google search API key I use normally.

If I want to build an application for del.icio.us for example to offer a cool visualization of all your bookmarks, and you in context of other people who are close to your bookmarking activities, it’s essentially impossible without everyone volunteering their username and password in the clear to me, data about your bookmarks in del.icio.us is behind a firewall unless you sit on the RSS feed and store the aggregation. It’s the same with last.fm, who don’t even offer an API to recover your listening data (which is why I built a last.fm proxy). It’s up to del.icio.us or the service provider as to what they want to offer, but from the developer perspective, a lot of gratuitous authorization and api keys are essentially just another barrier to building the application I am interested in building.

User:alex: Alex Bosworth's Weblog

Private Bookmarks Web Service

It seems to be a trend: if you’re using web applications, forget about privacy. Forget about owning your own data.

A while ago, I had an issue with this aspect of del.icio.us. Once upon a time, there was no way to save private bookmarks: it’s still pretty obtuse. Well, I hacked up something to get around the limitation and create bookmarks anonymously or semi-privately if not privately.

It was just meant to be something to bookmark for myself and maybe something to blog about, but people took to it, and over 11k private bookmarks were saved using it in the space of 8 months. However a short time ago, Yahoo/del.icio.us blocked the service: not only could I not post new private bookmarks for myself, all the ones I and everyone else had saved were wiped out.

Well ok, lesson learned. But I still want to bookmark privately, and I don’t like the way del.icio.us does it: public and private bookmarks are not chocolate and peanut butter, they should be separate. And private bookmarks should be really private, I don’t even want to trust the servers with them.

So I’ve coded up an open source solution: a web service that lets you post bookmarks that even the server doesn’t know about.

How it works is that just before you post a bookmark, your browser encrypts the data and sends the bookmark information encrypted with your private key to the server. To browse your bookmarks, the server sends them back encrypted and your browser then decrypts them.

A special bookmarklet can be used on remote web pages to post, or you can post directly via the interface.

Because of the heavy use of browser encryption and decryption, the entire application is written in JavaScript/Ajax.

Also, if you have used my previous private bookmarks solution, please email me at alex.bosworth+projects at gmail – I’ve set aside your username and I’ll import your bookmarks that were blanked into the new service.


For those interested, I’ll go into some details on how the application was developed:

Developing an encrypted bookmarks web application

I’ve been working on this project in my spare time since a few months ago when Yahoo/del.icio.us gave me the final word that priv.at was blocked for good. There are several challenges to an encrypted bookmarks service that needed to be overcome:

  1. Paucity of quality open source web browser encryption and decryption libraries
  2. Developing a bookmarklet that doesn’t betray the url to the server
  3. Storing an encryption key on the browser beyond a single page load, without persisting it to the server
  4. Ensuring that encrypted data doesn’t become corrupted
  5. Keeping a javascript application fast
  6. Dealing with pages with content that all has to be decrypted
  7. Search and tagging without the database knowing what it’s searching for

The first problem of finding a suitable library was just a matter of going through various libraries, looking at the code and running them through unit tests. Most javascript encryption libraries however were designed as proof of concepts, or coded in very ugly ways, or not for any kind of performance and are therefore very difficult to adapt. This just took methodical testing to find one I liked. I then extended the string object with a .encrypt and a .decrypt method, this allows for encryption to be a simple component of the application.

The problem of developing a bookmarklet is that traditionally you encode the url in a get parameter, and then the server echoes what you asked it to ‘get’ when you hit the post screen. But that implies that the server knows what urls you are interested in. I wanted to avoid that, so my bookmarklet uses the only part of a url that is not passed to the server: the hash.

Storing an encryption key on the browser was another issue that I didn’t really anticipate. It is quite annoying to have to type in your encryption key every time you want to see your bookmarks or post a new one, you get used to being just logged in and having the server remember that you authenticated and it can send you privileged information. But that doesn’t work in this case, you must never tell the server what your private key is, but somehow have JavaScript remember it from page load to page load, which is not something that JavaScript seems to have been designed for. Luckily, the dojo toolkit provides a JavaScript to Flash bridge that allows for permanent storage on the browser, something normally of limited use, but perfect for my purposes.

This was my first practical use of the dojo javascript toolkit, and I have had a mixed experience. I have found on the one hand it’s fairly elegant as an API, provides the functionality I need, and is generally very powerful. On the other hand, it doesn’t always work quite like it should and it creates problems for Safari and Opera: I haven’t even tried IE yet. I decided the tradeoff of having to type your key in over and over was worth losing the minority browsers temporarily, and I’ll look at fixing that at a later stage.

Another problem that I ran into during development of the project was the fact that strange corruptions were taking place in some posts of bookmarks. I would post a bookmark, and it would sometimes return from the server garbled. I could post something 5 times in a row, and 4 could return fine and the fifth would be corrupt. This made it one of the more frustrating issues to pin down. One issue that was obvious is that I had forgotten that encrypting the strings would make them too large for MySQL’s maximum varchar space of 255 characters, which is usually ok for a title and a url.

Another issue is that the encryption library I use doesn’t encode to hex, so it makes data transmission and application design a little more complicated. My normal style of writing JavaScript is to keep everything in the document. Building web applications, you might have various stages of data representation: a database schema, an object schema, a javascript object schema, and finally a document schema. A bookmark is one thing in the database, another as a server object, another as a javascript object, and another as an html node. Because of this, my practice is to generally avoid JavaScript variables and store everything right in the html. I also try to avoid generating html in JavaScript, I prefer to keep things simple and leave all the html generation to PHP.

Except that I discovered that storing the encrypted bookmarks in the document would corrupt them. This meant that PHP had to become a generator of JSON instead of HTML, and JavaScript would then take over the job of generating the pages. The data transmission issue was solved by tracking down the appropriate escape functions in JavaScript and storing the bookmarks in the database escaped for JavaScript.

Finally, all this JavaScript made the application slow, encryption is a processor intensive business and Firefox’s JavaScript engine is sluggish at best, so I’ve limited the number of bookmarks on a page to 15 and tuned the JavaScript to avoid excessive DOM manipulation, which is the biggest CPU killer out there.

Oh yes, lest I forget: tagging. I decided to leave that out for the time being. The server can’t search for a tag, because the encrypted text is different even for the same word encrypted with the same key. Even the same word encrypted twice in a row is not the same. This of course means that I can’t prevent users from posting the same bookmark twice.

If I wanted to implement tagging/search, I would need to either use a different type of encryption that gave back the same result for the same input, or I would need to burn CPU on maintaining a dictionary on the browser side. The original priv.at del.icio.us bookmarks didn’t have tagging, I can still look through dates and page quickly through my bookmarks, so I have left that feature out as being too CPU intensive for a first pass at creating a quick bookmarking application.

Of course I have also published the project source as GPL v2 for those interested.

User:alex: Alex Bosworth's Weblog

SWiK's 1st Birthday

One year ago, I shipped the first version of a project for an open source community resource we initially had codenamed project stratocaster.

It’s been a fun road, and we’ve learned a ton about what it means to run a public community driven site, as well as slowly refining through practical use a very cool wiki platform.

What I’m most happy about is that SWiK is over time becoming a more useful resource, and each month we see more people visiting and contributing than we did the previous month.

Here is a picture of our monthly visitor growth so far, from the beginning of the rewritten swik v2.0:

The History of SWiK

Project Stratocaster was long in planning, and went through various rejected ideas on how we might make a site that was compelling and useful in the web market that is already flooded with interesting and useful sites. Eventually I worked out 3 basic ideas on what we might build SWiK around: a comprehensive compendium of what matters in open source software: a timely resource you could use for up to the minute information about these topics, and a personal resource that anyone make their own, something that wasn’t ours alone but that we let anybody who was interested control.

Over a few weeks I quickly knocked out a prototype and gave a demo of how we could provide this kind of service using RSS and webservices to help SWiK integrate with existing services, tags to help categorize and cross reference, a simple web interface to create and find information. Based on the demo, we decided to go ahead and build out and ship Project Stratocaster.

I had never developed this kind of thing or any real shipping product before, but we had just shipped and were promoting a custom PHP stack, so building SWiK on this stack seemed a natural choice and PHP is a great language for rapid prototyping and development.

After an initial demo, we decided to turn my prototype for SWiK into a shipping product, using the protype code as a base. Work continued on the prototype, but designed as a proof of concept, the prototype had large holes that needed fixing before we could think of shipping it. Most importantly, skipping input validation steps I had left huge security holes all over the code, being unfamiliar with MySQL optimization my pages were not performant to our guesstimates of initial traffic numbers, and generally the product was unpolished. To help get things ready we brought in Marc Wandshneider, who had recently written an excellent book on application development in PHP.

To be frank, the prototype née swik v1.0 was an unholy mess when Marc came on board, and it’s amazing that we were able to get things up and running enough to ship in as short a time as we did. At this point I had no training or practical experience in writing maintainable code, and compounded by the use of PHP 4 instead of 5, I had created a 3000 line 1 file monster without many newlines and very few comments.

Marc however is very experienced in writing good maintainable code, and the 3000 line monster was split and refactored and version controlled and editted into something shippable, which we did ship in June of 2005.

Our first logo, designed in MS Paint by Marc

Designing a community site from scratch is quite a difficult task, because you are operating against a large set of assumptions about how the site will actually function when you ship it. A community site specifically, you have to think each step of the way how it can be gamed and attacked by spammers and vandals, who plague all social sites from the first second.

The defense we used against spammers in version 1.0 was two parts: the changelog and the obfuscation defense.

As you can see in sites such as Wikipedia, it’s possible to have a large body of information that is editable by anyone at all, so long as you channel the body of edits behind the pages into a manageable set of recent edits. Users can then keep an eye on this management set of data and act as a filter on new information coming into the site, making sure that although there are thousands of edits, they have all passed through a filter that ensures that they are not spam or vandalism. This anti-vandalism and anti-spam approach led to the ubiqitous undo buttons and the very early development and planning around what is possibly our most complex feature: the changelog.

Unfortunately, there is a simple way to defeat a wiki recent edits filter. Simply bombard it with more changes than can be reasonably monitored, and the filter will break under the strain. The easiest way to do this is to automate vandalism and spam, which is done to great effect by botnets all over the internet. My blog for example now receives a spam an hour, which makes it hard for me to publish any comments over the general cacophany of unwanted crud.

Automated spam engines work by scanning for simple keywords in forms, such as ‘homepage’ or ‘name’ – they then fill these forms with junk and post them, thousands of times over. Thus to prevent these automated bots from catching SWiK’s forms and filling them with spam, all the form names were obfuscated: homepage became H0M3P4G3. This was actually quite effective one year ago, and will still today reduce spam received, as I test with various honeypots.

With these defenses in place, we shipped the project with our new name SWiK.net.

SWiK Version 1

Initially the plan was to test our assumptions about how the site would operate by not announcing SWiK to anyone. The site would only grow hollistically, without any press or announcement of any kind. Users and use trickled in, but I was able to figure out some important lessons about how people use web applications.

First, abuses of the site were way fewer than I had imagined. Social software abuse is a problem of scale, when small numbers of people can effect large numbers of people. When small numbers of people can only effect small numbers of people, there is no motivation for abuse, and thus it doesn’t happen.

Second, wiki markup is an absolute necessity. I had spurned wiki languages in the first version’s design, due to my disatisfaction with most formats, the complexity of developing a new one, and the inability of any wiki format to match the flexibility of straight html. This was a mistake, because editing large amounts of text with no formatting help is almost impossible for the normal editor, annoying for the experienced editor, time consuming for any editor, difficult to do collaboratively, and hard to audit in a wiki recent change log.

Third, folders and hierarchy are very bad things. In the initial design I copied a file system layout, with pages in folders and sub folders. This allowed for deep collections of pages that flowed naturally with a URL structure, but it proved to be a nightmare on the database, a nightmare in the changelog, a nightmare to find what you were looking for, a nightmare for UI design, and a nightmare for general use over the internet due to latency or general web surfing behavior in site navigation.

The final mistake was not having Ajax powered editing. The initial prototype way back when had used JavaScript driven forms to make editing quick and easy, but the complexity both in the code and UI design had made me decide Ajax was inappropriate for use in anything critical or complicated. I published my notes about Ajax development issues while working on SWiK v1.0 in May of 2005. But without Javascript help, web forms are too slow and cumbersome to be used casually, which doesn’t fit with the experience I wanted for SWiK.

Ajax was also needed for another feature of SWiK, which is automatic project creation. In initial prototypes of SWiK, merely searching for an open source project that was not in SWiK’s database would launch a process that would behind the scenes go out, research the project, create it, and then deliver the searcher to the created project page as if it existed all along. This was toned down to require a further confirmation click, but problems with this were apparent as soon as you moved out of the demo space, as people search for the most random of things, cluttering the database with useless garbage and taxing the webservices we used to find the project information. These webservices were also prone to failure, leading to problems servicing the new project requests. It was apparent from this that we needed Ajax to asynchronously provide the information when and if the webservices returned it, and to never block on or require a 3rd party service to function.

Despite these mistakes, SWiK was an immediate success when we first launched publicly a month later attracting traffic beyond our expectations, in fact the attention brought our small initial server to its knees with the number of new projects being entered and information added.

SWiK version 2.0

This success prompted work on an ambitious redesign and complete rewrite of SWiK, version 2.0. Version 2 would involve a longer development cycle and we brought in Jerry to complete the project.

Version 2.0 design was started before v1 was even launched, based on the problems listed above, there were serious design changes necessary to move forward. Complicating things was an increasing spam and vandalism problem as we grew, necessitating the development of countermeasures beyond simple form name obfuscation. Additionally to grow we would need to redesign the pages to scale to much larger targets. To put things into perspective, the rush of traffic we received in the first few months of SWiK are today equalled by a few days of current swik traffic.

Most complicated of all, as we were moving forward, we couldn’t just discard the edits already contributed by visitors, so any redesign would have to take into account migrating from an existing data set.

Additionally, maintenance on the SWiK 1.0 site still in operation would have to continue, even though any code for SWiK 1.0 would have a very short lifetime.

The design for SWiK 2.0 involved a lot of radical changes, focusing on keeping everything that worked in the first version: RSS integration, free tagging, webservice integration, anonymous editing, etc. The hierarchy would go, and be replaced with tags. Every single form would be replaced with an Ajax powered form. The URL schema would change to be simpler. Textile wiki markup would be introduced. Tags and Projects would collapse into a single concept: tags. 5 basic templates for pages would be introduced. A comment system would be attached to all pages. A login system would allow users to take credit for their edits after they had made them anonymously. The RSS backend would need to support thousands of feeds instead of tens or hundreds. Tags would use a more complicated but more scalable heuristic to determine tag popularity. Elements of the interface would be optionally Ajax driven for powerful navigation within pages. The changelog would be radically altered to introduce dynamic change groupings to allow for a more manageable stream of edits. Users would now get their own wiki pages. Ajax would now power the auto project creation. History would now include more details and history display would change dramatically. Wiki links would indicate creation status of linked pages. Many other changes were also implied.

The bulk and scope of these changes and the messiness of the prototype derived version 1 led us to the conclusion that development should start from scratch, in PHP5 to allow for an object oriented maintainable project that could grow to meet future demands. We would redesign the database as well, and use InnoDB, transactions, and foreign key restraints to avoid data corruption that had caused a few problems in the first version.

Furious development ensued, with key difficulties involving the migration of old data that had a fundamentally different schema and history model, the development of the improved tag heuristic algorithms, and a redesigned changelog page.

A week after our end of September goal we took SWiK 1.0 down, migrated all of the old data, and released SWiK v2.0 to the world. It was sorely needed, by the end of SWiK 2.0 development we had virtually ceased maintenance of the SWiK 1.0 codebase that was about to be discarded, and bugs and problems in the first version were making themselves increasingly apparent to visitors and editors.

We formally announced SWiK 2.0 at the beginning of October, and traffic just took off to the new version. The first month of release received five times as much traffic as the month before it, and after that traffic tripled or doubled every month until steadying to slower percentage growth in January of 2006, this also coincided with a development hiatus on the project, which saw Marc leave for travels abroad and our search for a new engineer to take over.

SWiK version 3.0

SWiK version 2.0 was a great release with solid legs, but over time a number of problems with the design of SWiK 2.0 made themselves apparent. During the development hiatus, I took time to work on a new specification, and by this time I had switched to doing all specification on our internal version of SWiK, which SourceLabs now uses for all specification and internal documents. After much searching we found Daryl, and development began anew on the next version of SWiK. (We’re still looking for another developer btw!)

One basic problem with SWiK version 2.0 is that there were so many changes and so much to reimplement we just couldn’t fit everything into the development cycle and a lot of good ideas had to be pushed out.

As traffic rose and time went on, spam and vandalism rose and became more sophisticated, again prompting a need for a more sophisticated defense.

Other problems included a page design that was cluttered with too many features, a frustrating lack of diff highlighting in the changelog, too-flexible wiki templating that didn’t emphasize the right way to create pages, too much Ajax used for navigation, hard to use tag clouds, hard to use tagging, and a myriad of other small complaints and problems, including basic reliability and performance of various pages and components.

To fix a lot of basic problems, I designed a new user interface for all the pages. I cut features all over the place, whatever didn’t work was scrapped, to some people’s chagrin even things that did work were cut back in order to emphasize what was important.

The new design is focused on empty space, this is designed to make getting the central information of a page obvious and easy, you can find it easily as there’s nothing else on the page. Page creation, which used to involve more buttons and knobs, has been trimmed to bare essentials. A large icon now gives an identity to a page, so that different pages about different subjects are easy to identify. Tags now feature prominently and are autosuggested for ease of use. SWiK v3.0 is a release of a thousand little changes and tweaks to streamline and improve the fundamental ideas behind SWiK v2.0.

There’s one important thing that we learned the hard way in SWiK v1 and v2: Don’t release big. Small incremental releases are so key, both to development sanity and for design intelligence. Traffic metrics will tell you with every release how well it worked and what you need to fix, but you can’t get any metrics if you don’t release.

It’s been 1 year of SWiK and we’ve come a long way, thanks to the community of editors and a lot of hard learnt development and design lessons. But it’s definitely rewarding, and I think we’ve built a great product and a good start to what in future major releases will be much much better.

And it’s certainly gratifying that for SWiK’s first birthday we just passed 1 million unique visitors served, and went over 10,000 wiki pages created. Thanks for your edits and contributions to making a useful free resource for people who are using open source software, and stay tuned for a lot more to come.

User:alex: Alex Bosworth's Weblog

Rocky Shoals of Ajax Development

A year ago, I started a list of Ajax Mistakes that grew and eventually moved to a collaborative page, where other people could post or edit what they saw as issues in Ajax development.

That list focuses on basic application design mistakes when working with Ajax, such as breaking the back button and using GET and POST requests improperly.

But the specifics of Ajax development are equally perilous to basic application design. The siren’s call of the XMLHTTPRequest object can lead many brave scripters to a demise on the rocky shoals of browser limitations and bugs.

So in the interests of charting out these limitations and bugs, I’ve started another list devoted to these limitations, quirks, and bugs. It’s separated into 3 parts: Basic Browsers, IE, and Firefox.

Again, this post will live on in a collaborative wiki page for future updates.

Basic Browser quirks and limitations

  1. XMLHttpRequest can’t access remote servers. For some odd reason, although there are ways in javascript to send and receive data to remote servers, such as through script or iframe elements, XMLHTTPRequest cannot have a remote server as a target. This is a basic cross browser security rule that may not be immediately obvious to the newcomer to Ajax development.
  2. Multiple Ajax Requests are not fired in order. IE, breaking from a long tradition of ignoring independent standards, chooses to follow the HTTP 1.1 RFC 2616 to the letter, which means that IE may only have two XMLHTTPRequests open at a time; after which IE will retain an internal queue of requests which will be serviced in no particular order. Even if the requests are fired in order, the nature of the internet dictates that they will not be received in order, so never write code that assumes xmlhttprequests will be sent in a particular order.
    • Firefox also has a similar albeit more liberal limitation in the number of simultaneous xmlhttprequests that may be open; however In Firefox 1.5, the developer may modify the priority of the internal request queue.
  3. Asynchronous XMLHTTPRequests responses will arrive in no particular order. As implied by the word Asynchronous, XMLHTTPRequest responses may arrive at any time in an unpredictable order that is ignorant of developer intent, happily executing callbacks in the random order in which they eventually wind up on the client.
  4. XMLHTTPRequest does not requires the use of XML. While Ajax is aptly named when it comes to asynchronous execution, it is poorly named when it comes to XML. The XMLHTTPRequest object has a useful method called responseText that delivers the straight text of the response, be it XML, JSON or just simple unadorned text. Using JSON or simple text can be much faster, easier, and more concise than XML.
  5. Ajax uses UTF-8. Normal forms are sent using the encoding of the parent page. Thus a SJIS encoded page will default to sending form content encoded in SJIS. Ajax submitted forms on the other hand will be sent as UTF-8. If for some strange reason, UTF-8 is not the character set of choice for the server, this will require a solution such as the server recognizing and translating UTF-8 responses to a desired character encoding.
  6. Ajax requests are url encoded. A bug relating to this can currently be seen on Digg.com. Submit a comment to digg, and then edit the comment to include a unicode character. The updated comment, sent via Ajax will be added to the database as the url encoded string: resulting in an odd looking url encoded comment.
  7. XMLHTTPRequest cannot transmit files. In a javascript heavy application, a developer might need to include the ability to send files without completely refreshing the page. XMLHTTPRequest however does not include this ability. Instead, a hidden iframe can be used to send the file, and Javascript can simply inspect the iframe. Ajax techniques can further complement this, for example the open source project Uber-Uploader can show a progress bar while uploading a file.

Firefox quirks or bugs

  1. Synchronous XMLHTTPRequests lock up Firefox. The XMLHTTPRequest method provides a third argument, which defines whether the Ajax requests are submitted synchronously or asynchronously. (xmlhttprequest.open(‘GET’, ‘http://www.mozilla.org/’, false);) On Firefox, setting this value to false will submit the xmlhttprequest synchronously and lock up the entire browser.

IE quirks or bugs

  1. XMLHTTPRequest Objects are not reused in IE. Unless the abort method is used, XMLHTTPRequest objects in IE won’t function after the first use, unlike in other browsers such as Firefox. A solution to this is to create a new XMLHTTPRequest object for each connection, although some fear this causes memory leaks, there seems to be no conclusive proof of this, as long as the known closures memory leak issue is avoided, as detailed in the next gotcha.
  2. IE doesn’t use cached images when Javascript inserts HTML with images. This is a general Javascript behavior, but with Ajax heavy applications that insert a lot of HTML snippets, this can lead to a lot of unnecessary image redownloading. The way to solve this is to send all images with proper Cache-Control, ETag, and Last-Modified headers. IE will request images with a ‘If-Modified-Since’ header and the server should send back a 304 header which will tell IE not to redownload the image, and use its cached image.
  3. Closures with circular references in IE cause memory leaks. It’s common in Ajax to use closures, however in IE if a closure has a circular reference, it will cause IE to start leaking memory. In Javascript it’s easy to create closures with circular references, so care should be taken to avoid memory leaks.
  4. Avoiding aggressive caching in IE – even with proper ‘no-cache’ headers, IE caches get requests – this can be solved by changing the get request query string with every request.
  5. IE corrupts gzipped javascript files. Although this is a more general issue with IE’s handling of gzipped content, in Ajax applications where there is a lot of Javascript, developers may be tempted to gzip their javascript to allow for faster page loading and lowered bandwidth consumption. However IE has a known bug where it cuts off downloads in mid-file, corrupting the javascript file.
  6. IE doesn’t cache gzipped Javascript files. Adding to IE’s poor handling of gzipped content is IE’s lack of support for simultaneous gzip and ETag cache headers. Again, this is wider scope than simply Javascript, but it means that even if IE didn’t corrupt the gzipped javascript, it wouldn’t cache it anyways.

I sometimes make mistakes, or overlook things. If you know of something that I’ve overlooked or have found something that I’m wrong about in this post, please contribute your knowledge directly to the wiki page for this list.

Further reading

User:alex: Alex Bosworth's Weblog

The Little Things

There’s a lot that goes in to making software products. A constant battle between shipping pressure and feature completeness that leaves behind a bloody trail of cut features and half-finished products. With every feature, you have to consider that it needs to be added to the test regimen, it may take more development time than projected, it might not actually be used by anyone, it adds clutter, it might impact other code, or that it might be only half thought out. Mostly it’s a good idea to simply cut everything only a small minority will use. Apple especially is ruthless in this regard.

But there’s another class of features, the little detail features that are easy to overlook but critical to making a product people don’t just use, but love. The bud-vase of the VW Bug. The gargoyles on the Chrysler building. The charging battery display on the Prius.

Here are some examples from software of features that whenever I use them, I think, I’m so glad that made the cut.

  • Digg’s Digg this. The animation is a big part of why that’s cool, but also the fact that I can see right in front of me how I’m changing the site makes the interactive nature of Digg tangible. (One interesting paradox of Digg is that even though stories are driven to the front page by people ‘digging’ them, the comments are always filled with people saying the stories are complete crap. This may be pent up desire for a negative Digg button, a weakness of the comment moderation system, or maybe it’s just that when everyone feels like an editor, everyone wants their say in what fits and doesn’t fit.)
  • Adium’s Flapping duck. When you get a new message, Adium’s duck in the dock starts flapping its wings to get your attention. It’s actually a bit subtle, but it’s a really cool use of the dock.
  • Del.icio.us Tag addition. If I want a javascript library, I visit http://del.icio.us/tag/MVC+PHP. It’s actually a feature only 1% of the del.icio.us users use, but it makes the site for me. Even the fact that the URLS are clean and readable is something probably only a fraction of people take notice of, but I love it, and I put it in SWiK: http://swik.net/MVC+PHP.
  • GMail’s Keyboard shortcuts. I’m pretty sure that only a small minority of GMail’s millions of users actually know the keyboard shortcuts in Google. Even if lots of people aren’t taking advantage of hitting ! on a message to send it to the spam folder, or ‘o’ to open an email, it’s a feature that makes me love GMail.
  • Bloglines’s and Adium’s Friendly error message. Don’t get me wrong, I absolutely hate it when things break, but seeing a fat plumber or a duck going down in flames somehow tempers my ire. I gave a shot at replicating this on SWiK’s error page with soothing language that helps people understand there are people behind the code, but nothing really says we screwed up and we’re sorry like a duck going down in flames.
  • Mac OS X’s hibernate feature. When you use Windows on a laptop, you get used to the fact that when you close the lid, your laptop is going to a special hell from which it may never escape. On OSX closing the lid is like turning off a light switch, by the time you’ve opened it, it’s ready to go.
  • SWiK’s Register after the fact. I came up with this feature so that even if you’re not logged in, SWiK remembers changes you make to pages, and lets you then create a new account or login to take credit. Every time I forget to log in before making edits, I think, “damn I like that feature.”

Little features that fill in the details make all the difference in the world.

User:alex: Alex Bosworth's Weblog

Google Reader API

there's a secret google reader api - very interesting

User:alex: My Bookmarks

Optimize for fun

People aren't robots

User:alex: My Bookmarks

Locomotive - SWiK

Locomotive is a flexible one-click solution to Ruby on Rails development for Mac OS X 10.3+.

User:alex: My Bookmarks

User:jerryk

Welcome!

I’m, Jerry Kuch, one of the developers (along with Marc and Alex) of SWiK. I’ve worked on many things including operating systems, multimedia, security and crypto software, niche embedded stuff, broadcast video, a couple of web applications, mathematical programming environments (computer algebra and statistics mainly), virtual machines, network appliances and likely some other things that aren’t coming to mind just now.

Recently I’ve been working in and around:

  • The Java virtual machine
  • Functional programming languages, particularly targeting the JVM
  • Statistical computing, R and SPLUS
  • Haskell, type systems, monads, concurrency
  • A smidgeon of Ruby, Rails and scripting on the side.

I’ve recently been working on a couple of projects at once, but am now reaching the point that I can take a bit of a breather and look at something else. But I’m nearly always open to yakking about anything interesting, with somebody interesting.

I’m usually easy to reach at jerrykuch AT gmail.com.