Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ajax and JSON response bug in Internet Explorer (works in all other browsers)

For some reason IE is asking us to download a file instead of running it as ajax. This works in all browsers except IE. I tried messing with the headers that it returns with no luck.

The function grabs form data then post's it the response is a can be an array of any number of items to be updated on the page.

Its not suppose to be file its suppose to be just a json response.

PHP

header('Content-type: application/json');

$error = "The Email and Password you entered could not be resolved.";
$elements[0]['target'] = '.error_report';
$elements[0]['action'] = 'inside';
$elements[0]['data'] = '<p>'.$error.'</p>';
$this->output->set_output(
  json_encode(array("elements" => $elements))
);

Javascript

$(document).ready(function () {
    jQuery.ajaxSetup({
        cache: false,
        dataType: 'json',
        error: function () {
            alert("Request was not successful. Please try again shortly.");
        }
    });

    $(document).ajaxSuccess(function (e, xhr, settings) {
        var response = xhr.responseText;
        if (settings.dataType != 'json') {
            return;
        };

        try {
            response = jQuery.parseJSON(response);
        } catch (e) {
            alert(e);
            return;
        }

        if (response.elements instanceof Array) {
            var reqs = ['target', 'action'];
            var valid = true;
            for (var i=0;i<response.elements.length;i++) {
                var cur = response.elements[i];
                var sel;

                for (var j=0;j<reqs.length;j++) {
                    if (typeof cur[reqs[j]] !== "string") {
                        valid = false;
                        break;
                    };
                };

                if (!valid) {
                    continue;
                };

                sel = $(cur.target);
                switch (cur.action) {
                    case "inside":
                        sel.html(cur.data);
                    break;
                    case "instead":
                        sel.replaceWith(cur.data);
                    break;
                    case "remove":
                        sel.remove();
                    break;
                    case "refreshPage":
                        window.location.reload();
                    default:
                        if (typeof sel[cur.action] === "function") {
                            sel[cur.action](cur.data);
                        }; // else continue
                    break;
                };
            };
        };


            // Dispatch the AJAX request, and save it to the data object so that
            // is can be referenced and cancelled if need be.

            self.data('ajaxify.xhr', jQuery.ajax({
                url: this.action,
                type: 'post',
                dataType: options.dataType,
                data: (beforeSubmitIsJquery ? beforeSubmitResult.serialize()
                                            : self.serialize()),
                success: function (/**/) {
                    cleanup();

                    options.onSuccess.apply(that, arguments);
                },
                error: function (/**/) {
                    cleanup();

                    options.onError.apply(that, arguments);
                },
                complete: function (/**/) {
                    options.onComplete.apply(that, arguments);
                }
            }));
like image 865
Walker Avatar asked Aug 31 '10 21:08

Walker


1 Answers

Well, I ask because the behavior you describe has all the hallmarks of a double-post caused by an event handler launching an ajax request followed by the "native" browser form submit happening. If I were you, I'd make triple-extra-sure that your event handler is either returning "false" or calling "preventDefault", or maybe both :-) – Pointy 1 hour ago

My followup: Since IE ignores preventDefault, try using return false; after preventDefault ...

For future reference to other devs: the way that the common libraries tend to do this is they will usually code a block with both methods (preventDefault() and return false;) because this tells each of the major browsers to stop working the event, according to which they listen to. This is more important with legacy IE browsers.

Anyways, glad we could help.

like image 172
jcolebrand Avatar answered Sep 18 '22 13:09

jcolebrand