简体   繁体   中英

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);
                }
            }));

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.

I had this problem with ASP.NET MVC 4. I was returning a JSONResult. But by changing the return object to this.content fixed this problem.

[HttpPost]
public ActionResult Upload(AddNewModel model)
{
    /**...*/
    return this.Content(id.ToString());
}

So it appears that IE has a problem with a json object being returned, and can be fixed by returning a string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM