jQuery ajax:error runs even if the response is OK

2020-04-02 10:25发布

问题:

I have a form which submit a form via AJAX with :remote => true. Looking at the server log and FireBug, I get the response 200 OK and it returns JSON in the form of:

{ "email": "test@test.com"}

then I have these two handlers:

$('#new_invitation').bind("ajax:success", function(event, data, status, xhr) {
    alert('test');
});

$('#new_invitation').bind("ajax:error", function() {
    alert('error');
});

and even if I get back a 200OK, it is the error handler that fires. The only time I managed to make the success handler work was when I send a empty response with 200 in the header.

I can't figure out why this isnt working :-S

EDIT 1------------ After doing these changes:

$('#new_invitation').bind("ajaxSuccess", function(event, data, status, xhr) {
    alert('test');
});

$('#new_invitation').bind("ajaxError", function(jqXHR, textStatus, errorThrown) {
alert('error');
    console.log(jqXHR.responseText);
    console.log(textStatus.responseText);
    console.log(errorThrown.responseText);
});

I am still getting the same error. The log stuff gives me:

undefined
my_email@test.com
undefined

Here is the code for the form (standard Rails stuff):

<%= form_for @shoot.invitations.new, :url=>shoot_invitations_path(@shoot), :remote => true, :html => {:class => 'form-inline'} do |f| %>
    <%= f.text_field :email, :'placeholder' => 'ex: test@test.com' %>
    <%= f.text_field :role, :'placeholder' => 'ex: Photographer' %>
    <%= f.submit "Invite", :class => 'btn btn-success' %>
<% end %>

EDIT 2 ---------

I did a few changes and now it seems my error is a parse error. I dont understand because this is the JSON I am getting back from the server (data.responseText), which seems all good:

{"email":"zxxczxc@test.com"}

ANSWER --------- I managed to have everything work when I put :'data-type' => :json in the form options. I tried this before and it did not work because I put it in the form_tag options and not the html options...

回答1:

If the server returns something that isn't valid JSON, such as a single space, jQuery will generate a parse error and consider it a failed request even if the status code is 200.

As of jQuery 1.9 a completely empty response is considered a failed request when the type is set to JSON since an empty string is invalid JSON. See http://jquery.com/upgrade-guide/1.9/#jquery-ajax-returning-a-json-result-of-an-empty-string.



回答2:

  1. Check that $.ajax's datatype is set to jsonp

  2. Try to return {email:"ahsgah@ahsgh.com"}



回答3:

JSON.parse('') throws an error. To me, that is stupid, it should return undefined. I added this code to my app

#HACK JSON.parse('') should return undefined, not throw an error
_parse = JSON.parse
JSON.parse = (str) =>
  unless str == ''
    _parse.apply JSON, arguments

or for u poor people not using coffeescript ( untested )

//HACK JSON.parse('') should return undefined, not throw an error
var _parse = JSON.parse
JSON.parse = function(str) {
  if (str !== '')
    return _parse.apply(JSON, arguments);
  else
    return undefined;
}


回答4:

Use ajaxSuccess instead of ajax:success, and ajaxError instead of ajax:error for your eventTypes.

See here: http://docs.jquery.com/Ajax_Events



回答5:

(On Rails 5.2 and jQuery 2) I spent an hour comparing two bits of UJS code side-by-side to no avail: both return a similar format Javascript function call (to update the front-end), and a status of 200 but one triggers ajax:error and the other doesn't. I was able to eliminate the problem by switching from jquery_ujs to rails-ujs in the application.js manifest:

//= require jquery2
// require jquery_ujs  # Removed this by taking away '='
//= require rails-ujs

Note the hyphen vs the underline!

Now both calls behave the same (correct) way. I hope this helps someone else.