Hacker News new | ask | show | jobs
by mwcampbell 3744 days ago
The HTTP request for voting should be a POST request, not a GET request, since it changes state. So both the JS hack involving an image and the non-JS fallback are broken. The JS function should use XHR, and I guess the non-JS fallback should be a form with an image button, not a link.
3 comments

This code is simple, works reliably and has done so for a long time with no changes. That seems like the opposite of broken to me
But GET requests should be idempotent.
But it is idempotent in this case. The server keeps track of your votes, so regardless of the number of times you do the same GET, the result is the same.
At the moment, but in the future the browser might decide to prefetch the pages behind these links, hence voting against your will.

> (...) we may expand link prefetching support to include prefetching <a> tags, which include a relation type of next or prefetch in the future.

Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Link_prefe...

Hopefully the HN voting links never contain relation types which would imply prefetching! I recall that Firefox did some aggressive prefetching in the past, and some websites (maybe Wolfram?) temporarily blocked IPs which did the prefetching due to the extra load they were putting on the servers. It's very dicey, requesting URLs for a user which would have a low probability of being followed. Certainly, requesting tens or hundreds of URLs from a single HN page would be a reportable bug for either the browser (for wasting resources) or the site (for misrepresenting hyperlink attributes).

Regardless of all of this, if the HN server filters out duplicate votes, then the idempotence (is that a word?) of the request is satisfied, and it is OK to be a GET. [EDIT: after reading https://news.ycombinator.com/item?id=11308231 my point here is probably invalid, because voting is not a "safe" method. Voting alters the order of posts that future readers see, which is a material change for a discussion site. In contrast, something like a YT view-count tally doesn't effect a material change in the core material.]

Regardless of that, IMHO a GET request that changes the "fundamental" state of the world (not just UI state e.g. pagination/settings) is somewhat "rude" to begin with, because of the common expectation that GET requests are "harmless" and POST requests can change things. But like, that's just my opinion, man.

Actually, another way to do this is to create a form with the POST method that respond with status 204(which will not refresh the page). There is still no need to involve the XHR. I still think this solution is neat though.
"However, this is not completely true. It means: it won't change the resource representation. It is still possible, that safe methods do change things on a server or resource, but this should not reflect in a different representation."

http://restcookbook.com/HTTP%20Methods/idempotency/

It is possible to do so but may not be desirable anyway. It is completely possible to wire a fork bomb to the safe methods; you probably don't want to enable the bomb via crawler however.
I don't think that's referring to a case like this. I'd also argue that voting _does_, slightly, change the representation.
Only in the same way that watching a YouTube video changes the view count. Do you believe that's an invalid use of GET?