Bug Tracker

Opened 7 years ago

Closed 7 years ago

Last modified 6 years ago

#11850 closed bug (worksforme)

jQuery.ajax does not perform response with script Mime Type if status is 403

Reported by: Marc-André Lafortune <jquery@…> Owned by:
Priority: undecided Milestone: None
Component: ajax Version: 1.7.2
Keywords: 1.9-discuss Cc:
Blocked by: Blocking:

Description

The documentation states about the processing of dataType:

"script": Evaluates the response as JavaScript and returns it as plain text.

This is incorrect in case of a status code that is an error, say 403.

Please either:

  • Change the documentation to state under which circumstances the javascript will be executed, or
  • Change jQuery to execute the javascript no matter what the response's status code (as long as the content-type is "text/javascript", of course)

Personally, I vote for (b).

The status says if the operation was a success or a failure. It doesn't state what the content of the response is; that's what the type is for. If it is "text/javascript", then I feel that what needs to be done is to execute the JS. If that's not what the server wants, the server can either return another content-type or the appropriate JS.

Typical use case: There's a form. I click on "save". This fires some Ajax request. The server validates the form and there is something wrong with the data or the user is not authorized. The record is not saved, so the request was not successful. Server can return an error code, with some JS to display an error message, highlight the wrong field, etc... The 'success' callback of the ajax request will not be fired, since the request was not fulfilled even though it got to the server, it was not accepted by it.

I didn't check, but I assume the same argument can be made for parsing JSON, etc...

Change History (10)

comment:1 Changed 7 years ago by dmethvin

Keywords: needsdocs added
Resolution: worksforme
Status: newclosed

It just seems wrong to try and process the data type if the HTTP status isn't successful, so I'll mark this as needsdocs. We only try to process the data type if the status is 2xx.

comment:2 Changed 7 years ago by scottgonzalez

Technically, there's nothing special about 2xx status codes and the type of data returned by the server. It may be the case that many apps are not built properly and will respond with HTML for non-2xx status codes, regardless of what data type the user has requested. That is an application bug, and we should be aware that it's very prevalent and could cause problems if we blindly use the user-requested data type. However, if the server properly responds with something other than text/html, we could handle that appropriately. Ideally, we'd always trust the response headers and use that to determine what data type was returned. I think this is probably safe for non-2xx.

comment:3 Changed 7 years ago by Marc-André Lafortune <jquery@…>

Thanks for the +1. Hopefully with a couple of others this ticket could be reopened :-)

Indeed in no case should the user-requested data type be used (it can be multiple anyways), the content-type of the response is what matters. I also think that it would be safe to process json/javascript for non-2xx responses.

comment:4 Changed 7 years ago by Matt Murphy <matt.murphy@…>

I agree, jQuery should trust the response header's content-type and use it to determine the data type, and execute JavaScript if the content-type is text/javascript and so on. We are trying to do something very similar to the use case mentioned above (error message on page via JS). But, since jQuery doesn't execute JavaScript when there is a 403 (forbidden) error code we have to omit the error code in the http response, which isn't a good practice.

We could implement a failure callback on all our forms, but I feel like jQuery should always handle the content-type properly.

comment:5 Changed 7 years ago by dmethvin

Component: unfiledajax
Keywords: 1.9-discuss added; needsdocs removed

comment:6 Changed 7 years ago by Marc-André Lafortune <jquery@…>

For Matt Murphy and others, until jQuery-core fixes this, you can bypass the problem by registering a global handler like the following (in coffeescript)

  $(document).on 'ajaxError', (evt, xhr) ->
    if /^text\/javascript/.test(xhr.getResponseHeader('Content-Type'))
       eval(xhr.responseText)

This way you can send responses with javascript with the right error code.

comment:7 Changed 7 years ago by jaubourg

I dunno, I'd document it and leave it there.

Keep in mind we're just mirroring what a script tag does: it won't execute a script when the underlying response status code is in the 400s. Such status code is indicative of an "error" as far as the ajax workflow is concerned and, just like an exception would, it interrupts the ajax logic and provokes the rejection of the underlying Promise.

It's easy enough to use .then() (or .pipe() before 1.8) in order to take special actions in case of an error.

comment:8 Changed 6 years ago by dmethvin

-1, It still seems unexpected (at best) to have responses like 403 or 500 execute script. If someone wants to do that they can do it manually.

comment:9 Changed 6 years ago by mikesherov

-1, too much magic

comment:10 Changed 6 years ago by dmethvin

Voted out.

Note: See TracTickets for help on using tickets.