A HTTP 302 Found
redirect to PATCH
and DELETE
requests will be followed with PATCH
or DELETE
. Redirect responses to GET
and POST
will be followed with a GET
. The Rails form_for
helper will use a workaround to send POST
requests with a _method
param to avoid this issue for PATCH
/DELETE
.
If you make requests yourself, watch out for the following behavior.
When you make an AJAX request PATCH /foo
and the /foo
action redirects to /bar
, browsers will request PATCH /bar
. You probably expected the second request to be GET /bar
, since we're used to redirects always resulting in a GET
request.
# Browser sends
PATCH /foo HTTP/1.1
# Server responds
HTTP/1.1 302 Found
Location: /bar
# Browser follows redirect
PATCH /bar
# Server responds
HTTP/1.1 404 Not Found
This is also true on some browsers for DELETE
, or in general for any AJAX call that is neither GET
or POST
.
Some workarounds for this issue below.
Fix on the server: Redirect with a modern status code
If your redirecting action redirects with a HTTP status code of 303 See Other
the browser will always follow up with a GET
request, even if the requesting method is PATCH
or DELETE
:
def foo
redirect_to '/bar', status: :see_other
end
See Modern HTTP Status codes for redirecting for more background.
Fix on the client: Make a POST request with method override
The default configuration Rails and Sinatra includes a
Rack middleware
Show archive.org snapshot
that lets you control the HTTP method used for routing by POST
ing with a _method
param.
In jQuery this would be:
$.ajax('/foo', { type: 'POST', data: { _method: 'PATCH' } });
Since the request is now a POST
for the browser, it will follow a redirect with GET
as expected.
This is also what
Unpoly
Show archive.org snapshot
or the Rails unobtrusive Javascript adapter does when you annotate a link with data-method="PATCH"
.