Tuesday, March 14th, 2006
Using the HTTP Accept header for Ajax
<p>From one assessibility post to another. David Heinemeier Hansson has posted on Discovering HTTP #1: The Accept header.Rails 1.1 is going to have a new feature that uses the HTTP Accept header to allow nice degradation from Ajax enabled browsers down the stack.
The code example is:
-
class CommentController <ActionController::Base
def create
@comment = Comment.create(params[:comment])
respond_to do |type|
type.html { redirect_to :action => "index" }
type.js
type.xml do
headers["Location"] =
url_for(:action => "show", :id => @comment.id)
render(:nothing, :status => "201 Created")
end
end
end
end
If an old browser submits this form, we'll have it done through a plain old POST, which the browser sends along with a header like "Accept: */*". That means "I don't care what kind of response you give me, just give me something". Since the browser doesn't care, we'll decide what to do on the order of the type declarations. The first is type.html, so that's what we'll perform, which in this case simply instructs the browser to go back to the index.
If an Ajax-capable browser submits this form, Prototype will intercept the submission and turn it into an Ajax call. This call will be send along with "Accept: text/javascript, text/html, application/xml, text/xml */*", which specifies a preference order where Javascript is first, if not available, then HTML, if not, then XML, and finally it'll accept whatever if none of the preferred forms are available.
Notice how the Prototype preference order doesn't match the order of declarations in the respond_to call. That order was significant when */* was used as the Accept header, but when preferences are available, we';; do multiple passes through the declaration in search of a match. The order of declarations won't matter unless neither Javascript, HTML, nor XML is found.
Very nice. Seeing the magic "201" status code also shows how you can fake our old browser (so they can hit the backend without rerendering anything).
Related Content:











Or, you can simply try to fire XHR with Javascript. If it does not work, submit a synchronous request. Dual-mode without browser sniffing. See more at http://jspcontrols.sourceforge.net/. See live demo at http://superinterface.com/jspcontrols/index.html. Try turning Javascript on and off and see NO difference.