It’s just data

AJAX Considered Harmful

Please pardon the provocative title, but this post is intended to surface one point I buried in yesterday’s presentation in the hopes that by making it a separate post it will attract a wider audience.

I intend for this to post to be constructive, so I will focus on two specific suggestions which hopefully will serve as the seed for the development of a set of best practices for AJAX.  Here are the two humble suggestions on things that people should standardize on:

Rationale for these two suggestions follows.

Encoding

For the former, I proposed a simple test:

The first thing I want you to do is to copy the string “Iñtërnâtiônàlizætiøn” into your tool and observe what comes out the other side.

When expressed as a part of the query component of a URI, it should look like I%C3%B1t%C3%ABrn%C3%A2ti%C3%B4n%C3%A0liz%C3%A6ti%C3%B8n.

Standardizing improves interoperability, and the reason why I am suggesting UTF-8 is that it is backwards compatible with ASCII, can express the full range of the Unicode character set, and is widely implemented.

Idempotency

Looking into the current PHP implementation of SAJAX, you will see the following:

// Bust cache in the head
header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT");    // Date in the past
header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
               // always modified
header ("Cache-Control: no-cache, must-revalidate");  // HTTP/1.1
header ("Pragma: no-cache");                          // HTTP/1.0

This code should be a rather large clue that you are probably doing something wrong.  Apparently the author recognized that these headers are somewhat sporadically and inconsistently implemented, and hoped that by combining them that the chances of success would be improved.

The danger that the responses may be cached is actually the smaller of several concerns.  A much bigger concern is that unsuspecting grandmothers and bots everywhere can be tricked into modifying online databases simply by following a link.

Judicious use of HTTP GET can be a very good thing.  Perhaps toolkits can adopt a convention that procedure names that start with the characters “Get” use GET, everything else uses POST.


Sam Ruby: AJAX Considered Harmful

be sure to encode your apps correctly!...

Excerpt from del.icio.us/tag/ajax at

I may share some blame in that have dropped notes under XMLHttpRequest Caching.

IE’s XMLHTTP object caches GET requests while Mozilla’s (and probably the KJS version) don’t. That get’s into a fine line between what’s Javascript’s job and what’s the browser’s job.

The problem is if you have a method like “GetNewest”. Guess there’s a RPC discussion lurking there.


Perhaps toolkits can adopt a convention that procedure names that start with the characters “Get” use GET, everything else uses POST.

Sounds like a good approach.

Posted by Harry Fuecks at

Iñtërnâtiônàlizætiøn

This is a test to see if my URIs are encoded correctly. Anne claimed that a URI I had in Hebrew wasn’t properly encoded (in UTF-8), but I’m not even sure how to check. As far as I know I’m doing all my Unicode handling correctly (in UTF-8), but...

Excerpt from Keith's Weblog at

One of the problems is that only IE’s and Mozilla’s implementations of xml http request support anything other than GET and POST, it’s a great shame.  Safari and Opera have been pushed into implementing the object, it would be great if they gave us the full range of verbs, so we can really do useful stuff without running into these problems.

Posted by Jim Ley at

So I tried submitting a comment...

My browser includes the accept header:

Accept: text/html;application/xhtml+xml;q=0

I get back an application/xhtml+xml resource instead of the text/html one I get instead of the text/html I get if I make the same request without the application/xhtml+xml;q=0.  I’m pretty sure this isn’t a spec violation, but it’s certainly not friendly!

Posted by Jim Ley at

I remember a talk a few years back by Chris Shiflett at ApacheCon where he was talking about XSS, CSRF, and the like. Chris mentioned that one of the problems was that you could modify resources using GET. Roy Fielding popped up and mentioned that HTTP specifically declares GET (and HEAD) as idempotent. Alas, we’re forced to play in the real world, and it’s too late to shove that cat back into the bag.

Everyone knows that you use GET when you want to create a bookmarkable URL or have a short query string. You use POST when you don’t want people to bookmark the URL or you have lots of data. I feel the historical defaults and limitations of web browsers and servers have already reframed HTTP verbs beyond our control.

Fortunately, there’s no default HTTP method for XMLHTTPRequest, so there’s at least a fighting chance.

Posted by Adam Trachtenberg at

Shouldn’t the first semicolon be a comma instead?  E.g.:

Accept: text/html, application/xhtml+xml;q=0



Posted by M. Brubeck at

Sam Ruby: AJAX Considered Harmful

Sam Ruby has done more careful and detailed analysis of the issues associated with http writes AJAX Considered Harmful.........

Excerpt from 42 at

“One of the problems is that only IE’s and Mozilla’s implementations of xml http request support anything other than GET and POST, it’s a great shame.  Safari and Opera have been pushed into implementing the object, it would be great if they gave us the full range of verbs”

Safari’s underlying NSURLConnection class incorrectly implements PUT (drops the message body), among other things. This is fixed in Tiger, so maybe Safari 2 will be fixed as well.

Posted by Robert Sayre at

Jim: Can you provide more information?

$curl -I -H 'Accept: text/html;application/xhtml+xml;q=0' http://www.intertwingly.net/blog/
HTTP/1.1 200 OK
Date: Thu, 17 Mar 2005 00:57:29 GMT
Server: Apache/2.0.46 (Red Hat)
Last-Modified: Thu, 17 Mar 2005 00:56:32 GMT
ETag: "354637-5fd8-bb90f000"
Accept-Ranges: bytes
Content-Length: 24536
Vary: Accept-Encoding,User-Agent
X-Pingback: http://intertwingly.net/blog/pingback
Content-Type: text/html; charset=utf-8

Adam: while I tend to side with Roy, for the moment, let’s go with your definition.  The problem with the current AJAX toolkits is that they don’t allow people to pick the verb, so without them realizing it, they are creating “bookmarkable” URIs for all operations, including unsafe ones.

Robert: Thanks!  That would explain it.  Unfortunately, the result is still harmful.

Posted by Sam Ruby at

Sam Ruby: AJAX Considered Harmful

Wayne Burkett : Sam Ruby: AJAX Considered Harmful - "Standardizing improves interoperability, and the reason why I am suggesting UTF-8 is that it is backwards compatible with ASCII, can express the full range of the Unicode character set, and is...

Excerpt from HotLinks - Level 1 at

Iñtërnâtiônàlizætiøn

This is a test to see if my URIs are encoded correctly. Anne claimed that a URI I had in Hebrew wasn’t properly encoded (in UTF-8), but I’m not even sure how to check. As far as I know I’m doing all my Unicode handling correctly (in UTF-8), but...

Excerpt from Keith's Weblog at

“GET should never be used to initiate another operation which will change state.”

Those are TBL’s personal views. The TAG finding takes a more nuanced stance: “Dereferencing URIs is safe; i.e. agents do not incur obligations by following links.”

This more accurately mirrors the text of RFC2616. It even mentions the possibility of GET-with-body. Something without an obligation: a hit-counter. Maybe. I know you’re familiar with hit-counters that do incur obligations, like those tied to API keys.

Posted by Robert Sayre at

Robert, while I definitely agree that there are Shades of Gray involved in the boundary cases, there are clearly cases where HTTP GET should never be used.

Always using POST (like SOAP 1.1 does) may be suboptimal, but using GET for operations like CartModify is wrong.

Posted by Sam Ruby at

Here we agree. Someone with a more volatile personality might say “People building toolkits and deploying ‘REST’ systems with things like ‘CartModify’ in the URI have no idea what REST means.”

Posted by Robert Sayre at

Sam Slams SAJAX

“AJAX” is a convenient label for the architecture of applications like Google Maps and Visual Net from Antarctica Systems (which I founded). There’s nothing wrong with the idea. But Sam Ruby spots SAJAX, one of the first toolkits, going horribly off...

Excerpt from ongoing at

People building toolkits and deploying ‘REST’ systems with things like ‘CartModify’ in the URI have no idea what REST means.

Posted by MikeD at

A much bigger concern is that unsuspecting grandmothers and bots everywhere can be tricked into modifying online databases simply by following a link.

You don’t have to be clueless to be a victim of this trap. For an attacker it’s as simple as using those URIs as the src attribute in images, oder when referencing them as images in CSS-Stylesheets - you’re browser will issue a GET to that URI and you’ll never even know what hit you...

People who don’t understand this, should google for CSRF (Cross Site Request Forgeries).

Posted by Sencer at

Sam,  It works fine for accessing the site, it is only as a result of the POST when clicking the preview the button after typing the comment, and as M.Brubeck noted there was a typo in my report :

This is the equivalent CURL I believe:

$ curl -D 'headers.txt' -H 'Accept: text/html,application/xhtml+xml;q=0'
 -d 'parent=1928;title=AJAX%20Considered%20Harmful;Name=Jim;email=jim@jibbering.com;comment=Test;preview=preview'
 http://www.intertwingly.net/blog/

To which I get back:

HTTP/1.1 200 OK
Date: Thu, 17 Mar 2005 08:42:24 GMT
Server: Apache/2.0.46 (Red Hat)
X-Pingback: http://intertwingly.net/blog/pingback
Vary: Accept-Encoding,User-Agent
X-Pingback: http://intertwingly.net/blog/pingback
Transfer-Encoding: chunked
Content-Type: application/xhtml+xml; charset=utf-8

Which is also interesting in that it claims to not vary on Accept:, even though it clearly does.

Jim.

Posted by Jim Ley at

Sam Ruby's Ajaxian Practices

Sam Ruby has written a couple of practices that we should follow in Ajax applications: Encoding: the data should first be encoded as octets according to the UTF-8 character encoding Idempotency: GET should never be used to initiate another...

Excerpt from Ajaxian Blog at

AJAX Considered Harmful: Sam Ruby mit einigen kritischen Worten zu Ajax....

Excerpt from kniebes.net. at

Feedtagger

Feedtagger is an online aggregator, currently early prototype but already showing a great deal of promise. As well as a regular per-feed view, it supports tagging. Remember folksonomies, bit of a craze a week or two ago? That kind of thing. . The...

Excerpt from Planet RDF at

Ajax vs. winforms vs. ASP.NET - there is no right answer

”rich” browser applications using CSS, JavaScript and XML (recently termed AJAX applications) seem to be gaining in popularity. Mary-Jo foley has an article on MicrosoftWatch extoling their virtues, an article which sounds...

Excerpt from JCooney.NET at

There is much to be said for balancing knowledge with tact.

Posted by Mark at

Is there any overhead with a POST compared to a get with XMLHttpRequest? I’ve never really seen an article go into any detail.

Posted by James at

James, from a “bits across the wire” perspective, the primary overhead of POST vs GET is a blank line.

Posted by Sam Ruby at

Mark: you’re right

Posted by Robert Sayre at

Sam Ruby on AJAX

Sam Ruby some constructive comments on AJAX. First, use UTF-8 encoding for data. Second, use GET for what its supposed to be used for: getting. These comments are probably more broadly applicable than simple AJAX.......

Excerpt from Phil Windley's Technometria at

Good String for i18n testing

Found here: On a somewhat related article... the string is: “Iñtërnâtiônàlizætiøn” URI, it should look like I%C3%B1t%C3%ABrn%C3%A2ti%C3%B4n%C3%A0liz%C3%A6ti%C3%B8n."...

Excerpt from batalion.com/thoughts at

Three days worth

Forty five things I wanted to write about, just over the last three days....

Excerpt from phil ringnalda dot com at

RESTful coding standards

In AJAX Considered Harmful Sam Ruby starts to lay out a set of useful coding standards for REST. He addresses Encoding and Idempotency, however going a little further has helped me. I have tried to apply the KISS principal and be a minimalist i.e....

Excerpt from Fast Takes at

Anne

Sunday 20 March 2005 20:36 Of niet: [link] Over de naam: [link]...

Excerpt from GoT at

A few comments (after hacking on a “simple” not-unreserved URI character encoder).  First of all, you specify the URI escape sequence for `Iñtërnâtiônàlizætiøn` as:

I%C3%B1t%C3%ABrn%C3%A2ti%C3%B4n%C3%A0liz%C3%A6ti%C3%B8n

However, you fail to specify what character encoding you are using.  RFC 3986 states that the percent encoded characters of a URI can be in any encoding depending on the application.  So it doesn’t make sense to talk about what it would look like as a URI without also indicating that you used UTF-8 to encode it (at least, that’s my best guess).  If you used Latin-1 (ISO 8859-1) as a base, then the escaped URI will be:

I%F1t%EBrn%E2ti%F4n%E0liz%E6ti%F8n

I escaped that by hand using an ISO 8859-1 table on the web.  If anyone knows the UTF-16 - both little endian and BIG ENDIAN versions, if possible - I would love to know it!  I have an idea...

If you are testing Java software to understand `Iñtërnâtiônàlizætiøn`, use this code for the string:

"I\u00F1t\u00EBrn\u00E2ti\u00F4n\u00E0liz\u00E6ti\u00F8n"

If you are testing URI encoding software (like I am right now), append the string " -._~ " to that.  You should get the above escaped URI strings with "%20-._~%20" at the end.  The "-._~" part are unreserved characters and should be passed through unchanged (along with all alphanumeric characters).  The spaces ensure your software parses spaces correctly.  Many many many programs incorrectly pass spaces as “ ” or “+” instead of “%20” (which bugs me, since I have a %20 in my URL and nearly everyone’s software drops the % - grrrr).

I hope those tips saves someone the headache I had this weekend!

<i>P.S.  SR, your paragraph formatting is odd in Firefox (in the preview at least).  Paragraphs containing just the code blocks have little bottom padding.

Posted by Jimmy Cerra at

Guys,

POST support is included in Sajax 0.10 which I have just released. I’ve also posted a topic on the message board to help people understand when POST should be used instead of GET. I welcome other suggestions regarding Sajax and its standard compliance.

[link]

- Thomas Lackner, author of Sajax

Posted by Thomas Lackner at

AJAX (2)

Sam Ruby has started to write about AJAX best practices. A comment in one of his posts referred to a del.icio.us AJAX list which provided a pointer to the Ajaxian blog, which has a good amount of useful info about JavaScript libraries and more....

Excerpt from Muddy clouds at

Ajax? asynchronous JavaScript and XML

Well it looks like theres some push behind the AJAX naming now. I believe it stands for Asynchronous JavaScript and XML and translates into this easy to understand list. standards-based presentation using XHTML and Cascading Style Sheets (CSS);...

Excerpt from cubicgarden.com... at

<blockquote>If you are testing URI encoding software (like I am right now), append the string “ -._~ ” to that.  You should get the above escaped URI strings with “%20-._~%20” at the end.  The “-._~” part are unreserved characters and should be passed through unchanged (along with all alphanumeric characters).</blockquote>

The list of unreserved characters includes <code>-_.!~*'()</code>, in addition to the alphanumerics.

Posted by Porges at

Sajax Still UnSafe

This is apparently “per [my]  suggestions”. [Via  Tim Bray] Looking at the  code, SAJAX Version 0.10 now supports GET and POST interchangeably.  While this does have the desired affect of allowing requests of virtually any size, it does not... [more]

Trackback from Sam Ruby

at

First of all, blockquote requires a block-level element inside of it for valid HTML.

The list of unreserved characters includes -_.!~*'(), in addition to the alphanumerics.

Which spec is that from? unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" The !*() characters are sub-delims.

Posted by Jimmy Cerra at

^I see - that’s from the previous RFC for URI syntax.  Which one should I follow?

Posted by Jimmy Cerra at

Oops :)

Well 3986 marks 2396 as obsolete, so you’re right - although many applications don’t escape any of !*'().

Posted by Porges at

Misunderstanding REST: A look at the Bloglines, del.icio.us and Flickr APIs

I’ve slowly been appreciating the wisdom in using REpresentational State Transfer (REST) as the architectural style for building services on the Web. My most recent influences have been Nelson Minar’s ETech presentation entitled Building a New Web...

Excerpt from Dare Obasanjo aka Carnage4Life at

Smart web clients; Ajax way..

We have been hearing a lot about Ajax (asynchronous JavaScript and XML) these days. It is for sure changing the way web clients are presented. Why go far; Google maps (so called poster child for Ajax) /Google Suggest are the few ones to implement...

Excerpt from Rajesh about Prodigious revolution of Tech Life at

Ajax? asynchronous JavaScript and XML better known as Remote Scripting

Well it looks like theres some push behind the AJAX naming now. I believe it stands for Asynchronous JavaScript and XML and translates into this easy to understand list. standards-based presentation using XHTML and Cascading Style Sheets (CSS);...

Excerpt from cubicgarden.com... at

HTTP GET is an Attractive Nuisance

Paraphrasing Sam Ruby: Jon Udell: HTTP toolkits make it easy to do the wrong thing, hard to do the right thing. Dare Obasanjo: del.icio.us, flickr, and Bloglines use GET for edit resources. Sam Ruby: AJAX toolkits must beware of how they use GET....

Excerpt from More Like This WebLog at

Sam Ruby: AJAX Considered Harmful: "Looking into t...

Sam Ruby: AJAX Considered Harmful: “Looking into the current PHP implementation of SAJAX, you will see the following:...”...

Excerpt from Random Notes & Bookmarks at

The wrong end of the telescope?

Leigh Dodds, Mark Nottingham, and Ryan Tomayko have all suggested that, while client-side HTTP toolkits may contribute to HTTP abuse, server-side frameworks are more fundamentally to blame. Sam Ruby made a similar point in his post-ETech critique...

Excerpt from Jon's Radio at

Yes AJAX is probably harmful if you use primative technologies like PHP.
PHP ridden pages are harmful in their own respect ;)

On the otherhand with jsonrpc and cherrypy the server knows which request are jsonrpc request and which ones are normal request.

;)

Posted by nopa90 at

You were warned.

Read AJAX Considered Harmful. Read it very carefully. Read whenToUseGet. Read it very carefully. People get uptight about GET for...... [more]

Trackback from franklinmint.fm

at

Google Web Accelerator not ready for prime time

I uninstalled the Google Web Accelerator this morning after reading that it has some serious bugs that compromise users' logins to sites that use cookies for authentication. Basically, the proxies that the Google Web Accelerator connects to are not...

Excerpt from rc3.org Daily at

Backpack, Google Accelerator, HTTP

As often happens, Sam Ruby saved me from wasting too much time idly browsing the web (no energy to work on more important stuff on Friday night) with his latest post: This Stuff Matters. Sam links to a post by Robert Sayre on the Google Accelerator...

Excerpt from Ludo at

Google vs. Rails

Interesting to see what happens when two “well-liked” communities clash. Background: Google released a web accelerator, which follows the HTTP specs (AFAICT), but wreaks havoc with a category of Web 2.0-style apps which, for convenience, ignored the...

Excerpt from david ascher at

“Considered Harmful” Considered Harmful

Ever since the sixties, there has been a long-standing tradition of criticizing something well established by stating that it’s considered harmful—starting with the famous Go To Statement Considered Harmful paper from 1968 which pushed...

Excerpt from Pretty in Punk at

Sam Ruby: AJAX Considered Harmful

[link]...

Excerpt from del.icio.us/tag/ajax at

AJAX

Hace dos semanas escuché por primera vez via PC++ la palabra AJAX. AJAX son las iniciales de Asynchronous JavaScript and XML, una técnica del desarrollo web para crear aplicaciones interactivas: GMail debe ser el ejemplo que todos conocemos.Como en...

Excerpt from La última curda at

Ajax, un problème ?

Ajax, un problème ? Sam Ruby explique deux problèmes possibles d’Ajax : idempotence codage des caractères ajax, XMLHttpRequest [link]...

Excerpt from Karl & Cow - Le carnet Web at

Simple AJAX Code-Kit (SACK)

In this seemingly unlimited stream of AJAX articles and frameworks, let me present you to SACK. SACK is a light-weight AJAX API, written by Gregory Wild-Smith. Gregory writes: "I’ve seen AJAX solutions like SAJAX or Dojo, and they haven’t really...

Excerpt from Warping it up! at

Scrubbing bubbles and other cures for the common thin client application

My professional has a strong affinity with jargon and acronymns; so, it came as no surprise to me when “AJAX” was coined not too long ago by Adaptive Path. However, in the end I’m all the more convinced that AJAX, as with most technologies in the...

Excerpt from Craig's Musings at

AJAX, fashion, Google Maps and Flickr

AJAX (Asynchronous Javascript And XML) seems to be flavour of the month. First noticed in a mainstream online application on Flickr, subsequently on Google Maps and on the still (for me) mysterious Ruby on Rails....

Excerpt from cloudsoup weblog at

Enhancing User Experience to Affect the Bottomline

AJAX is having a tremendous effect on web developers (and website visitors). There have been excellent examples of it’s use popping up all over the web, along with warnings about best practices of using AJAX. Paul Scrivens points out that...

Excerpt from Brian Sweeting at

How to ReSTfully Ajax

Here are some pointers for learning more about the Ajax programming model and how to properly design your Ajax application : Ajax is said to be the cross-platform successor to Java... huh... (David, thank you for this pointer) Ajax should be...

Excerpt from AkaSig at

Spider Spamming

Spammers exploit search engine spiders.... [more]

Trackback from Musings

at

blogger import

Notify Blogger about objectionable content.What does this mean? [link] ——– AUTHOR: Random Stuffer DATE: 11/13/2005 06:44:48 PM —– BODY: CEO Book——– AUTHOR: Random...

Excerpt from quarter-random stuff at

Backpack, Google Accelerator, HTTP

As often happens, Sam Ruby saved me from wasting too much time idly browsing the web (no energy to work on more important stuff on Friday night) with his latest post: This Stuff Matters. Sam links to a post by Robert Sayre on the Google Accelerator...

Excerpt from Ludoo at

Atlas and Ajax-based APIs are really hard to maintain, and its client side architecture breaks server-side API.
zumiPage for ASP.NET is a better solution.
[link]

Posted by Amir Leshem at

REST and Web Services links

I’ve been doing some research into REST and web services. Here’s some links I found helpful. Paul Prescod: Common REST Mistakes (Date unknown) Sam Ruby: Shades of Grey (Sept 2002) Sam Ruby: Vacant Space (Sep 2004) Mark Pilgrim: RESTagra (Sep 2004)...

Excerpt from Just Looking at

Sam Ruby: AJAX Considered Harmful

Someone at Smarking has bookmarked your post.... [more]

Trackback from Smarking

at

I’ve found that you can’t set an element’s innerHTML from Ajax with UTF-8 encoded html.  You get a bunch of circumflexed As (\xC2 or &acirc;) next to normal entities like &nbsp;.  The way around this is to UTF-8 decode the html first:

function decode_utf8( s )
{
  return decodeURIComponent( escape( s ) );
}
(from [link])

Shane

Posted by Shane at

Sam Ruby: AJAX Considered Harmful

The bad things about AJAX...

Excerpt from Public marks with tags harmful & javascript at

Backpack, Google Accelerator, HTTP

As often happens, Sam Ruby saved me from wasting too much time idly browsing the web (no energy to work on more important stuff on Friday night) with his latest post: This Stuff Matters. Sam links to a post by Robert Sayre on the Google Accelerator...

Excerpt from Ludo at

Yup you do get a bunch of circumflexed As (\xC2 or &acirc;) next to normal entities like &nbsp;.  The other way I found useful is:

string = string.replace(/\xA0/g,' ');

Posted by Madhusree at

[from MiTaxi] Sam Ruby: AJAX Considered Harmful

[link]...

Excerpt from Delicious/url/f0e1c01062a88b23e02ce8bbdc9ac06f at

[from kangtime] Sam Ruby: AJAX Considered Harmful

[link]...

Excerpt from Delicious/url/f0e1c01062a88b23e02ce8bbdc9ac06f at

Add your comment