Ian Bicking: the old part of his blog

Re: GWA and RFC 2616

I have yet to see an example of something that can't be done without nested forms. People have used that as an excuse a lot, but nobody's given an example. It seems to me that a GET used in an unsafe way is equivalent to an opening form tag (with an action attribute and a method attribute with the value GET), a bunch of hidden inputs, a submit button, and a closing form tag.

Talking about nested forms as being necessary to replace unsafe GETs would appear to require people to be using nested links already, and they aren't.

Comment on GWA and RFC 2616
by Jim

Comments:

Here's an example:

<form action="edit_addresses" method="POST">
  Address 1: <input type="text" name="address-1" value="123 W. St">
    <a href="delete_address?id=1">delete this address</a><br>
  Address 2: ...
</form>

Happy? Yes, you could make edit_addresses process deletes as well (which is a semantic change to the form, though arguably a better user interface). Then the delete could be a button like <input type="submit" name="delete_address-1" value="delete this address">. But that's often a rather difficult change to make on a legacy application.

Personally I plan to put in rel="nofollow" on these links in the future; in many ways it seems like the best compromise, and a good indication of what I really mean (which is "no robots here", not "this item has side effects," which is not quite the same thing).

There's also other more subtle places where requests are pretty "safe" and certainly "idempotent", but the GWA will cause problems by following links. The most obvious being a webmail application where it would cause all mail to be marked as "read". Turning a mail read into a form submission would be really really bad UI.

# Ian Bicking

In the example you give, why not use a two-stage delete? The anchor "delete this address" would take the user agent to a confirmation that yes, indeedy, they'd love to delete the address. Then the actual deletion would be a POST, since the form has trouble with its being a DELETE.

However, I wouldn't go so far as to GET an item from my address book and have it magically appear in the trash (which could then be emptied on a POST). Misbehaving robots would then rip all the pages out of my book, and I'd need to dig around in the wastebasket looking for them.

With regard to the reading of mail, "reading" is a kind of GET. How do you tell the difference between a real person and a robot before you change the state?

# Will Cox

In the example you give, why not use a two-stage delete? The anchor "delete this address" would take the user agent to a confirmation that yes, indeedy, they'd love to delete the address. Then the actual deletion would be a POST, since the form has trouble with its being a DELETE.

I don't want to do that because sometimes deletes aren't that big a deal. Maybe they are undoable. Maybe it's assumed that lots of deletes happen. It's a UI concern, and sometimes it's appropriate to allow quick actions. It would be totally backwards to have HTTP methods driving the UI decisions like that.

With regard to the reading of mail, "reading" is a kind of GET. How do you tell the difference between a real person and a robot before you change the state?

You put it behind authentication where robots can't get to. Until Google uses users as a their trojan horse to get their robot claws on all the data hidden behind actions it can't take (because of robots.txt, POST forms, authentication, etc). Not that they are necessarily so sinister... but it's not impossible that they do intend to use GWA users as a way to find data they can't find on their own.

# Ian Bicking

Delete causes data loss, and thus is always a big deal. Think about how you use the trash can in your kitchen (or [=rm], if you prefer). Tossing something is an intentional act. Accidentally tossed the $50 Amazon gift certificate in the bin with the junk mail? You might want to retrieve that. If your trash can is an incinerator, you look twice at everything you toss in, or throw a whole bin's worth once a week. Maybe the action is undoable, and maybe it does need to be quick, but neither requires using a GET.

In the mail example, consider non-web mail user agents. They copy the messages from the server to your desk, but have you read those messages? No. Why should the cacheing of mail by your HTTP user agent indicate that the mail has been read?

# Will Cox

Delete causes data loss, and thus is always a big deal. Think about how you use the trash can in your kitchen. Tossing something is an intentional act. Accidentally tossed the $50 Amazon gift certificate in the bin with the junk mail? You might want to retrieve that. If your trash can is an incinerator, you look twice at everything you toss in, or throw a whole bin's worth once a week. Maybe the action is undoable, and maybe it does need to be quick, but neither requires using a GET.

In the mail example, consider non-web mail user agents. They copy the messages from the server to your desk, but have you read those messages? No. Why should the caching of mail by your HTTP user agent indicate that the mail has been read?

# Will Cox

> <a href="delete_address?id=1">delete this address</a>

What is wrong with <input type="submit" name="delete-id-1" value="Delete this address"> ?

# Jim