Posted over 1 year ago. Visible to the public. Repeats.

AJAX requests with PATCH or DELETE method will not redirect with GET

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.

Copy
# 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.

Workaround 1: Redirect with a 303 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:

Copy
def foo redirect_to '/bar', status: :see_other end

Workaround 2: Make a POST request with method override

The default configuration Rails and Sinatra includes a Rack middleware that lets you control the HTTP method used for routing by POSTing with a _method param.

In jQuery this would be:

Copy
$.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 the Rails unobtrusive Javascript adapter does when you annotate a link with data-target="PATCH".

Growing Rails Applications in Practice
Check out our new e-book:
Learn to structure large Ruby on Rails codebases with the tools you already know and love.

Author of this card:

Avatar
Henning Koch
Last edit:
over 1 year ago
by Besprechungs-PC
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Henning Koch to makandropedia