XMLHttpRequest在IE8与FireFox / Chrome中不同

时间:2010-09-29 18:05:48

标签: asp.net-mvc ajax asp.net-ajax cross-browser xmlhttprequest

我遇到类似于jQuery $.ajax Not Working in IE8 but it works on FireFox & Chrome的问题,但使用的用例不同。

我正在使用jQuery Form插件处理文件上传到ASP.NET MVC控制器,该控制器将文件发送出去进行解析和处理。如果抛出异常,它应该警告用户该问题。

//client side code
//make an ajax call, sending the contents of the file
                    $("#ajaxUploadForm").ajaxSubmit({
                        dataType: 'json',
                        url: '/plan/Something/ExcelImport',
                        iframe: true,
                        beforeSend: function () {
                            $(".ui-dialog-buttonpane").find("#my_progress").fadeIn();
                        },
                        success: function (data, textStatus) {
                            output = "<center><span class='flash'>" + data.message + "</span></center>";
                            $("#flash_message").html(output).fadeIn('slow');
                            setTimeout(function () { $("#flash_message").fadeOut() }, 5000);
                            cleanup();
                        },
                        error: function (XMLHttpRequest, textStatus, errorThrown) {
                            alert("XMLHttpRequest is " + XMLHttpRequest);
                            var contents = "";
                            for (prop in XMLHttpRequest) {
                                contents += "\na property is " + prop + " it's value is " + XMLHttpRequest[prop];
                            }
                            alert("the contents are " + contents);
                            alert("textStatus is " + textStatus);
                            alert("errorThrown is " + errorThrown);
                            //comes back in an HTML envelope. This should be parsed with regex, but I can't get it to work. Dirty hack
                            response = XMLHttpRequest.responseText.substring(XMLHttpRequest.responseText.indexOf("<body>"));
                            response = response.replace("<body>", "");
                            response = response.replace("</body>", "");
                            alert("There was a problem with the upload.\r\n" + response);
                        },
                        complete: function (XMLHttpRequest, textStatus) {
                            $(".ui-dialog-buttonpane").find("#my_progress").remove();
                            something_import.dialog('close');
                            something_import.dialog('destroy');
                        }
                    });

//server side code
public FileUploadJsonResult ExcelImport()
    {
        FileUploadJsonResult result = new FileUploadJsonResult();
        HttpPostedFileBase hpf = Request.Files[0] as HttpPostedFileBase;
        if (hpf.ContentLength == 0)
            return new FileUploadJsonResult { Data = new { message = "File contained no data" } };
        String fileName = Path.GetFileName(hpf.FileName);
        String timeStampedFile = fileName.Insert(fileName.IndexOf('.'),"_"+DateTime.Now.ToFileTimeUtc());
        string savedFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "tempo", timeStampedFile);
        hpf.SaveAs(savedFileName);
        try
        {
            result = ProcessFile(savedFileName, Request["Id"]) as FileUploadJsonResult;
        }
        catch (ArgumentException e)
        {
            this.Response.StatusCode = 500;
            this.Response.StatusDescription = System.Net.HttpStatusCode.BadRequest.ToString();
            Response.Write(e.Message);
            result = Json(new { message = e.Message, stackTrace = e.StackTrace }) as FileUploadJsonResult;  
        }
        return result;
    }

这在Chrome和Firefox中完美运行。在IE中,返回的XMLHttpRequest对象是不同的:

FF:alt text

IE: alt text

我一直在谷歌搜索XMLHttpRequest的浏览器实现之间的差异,但没有发现任何特定处理此案例。阻碍。

2 个答案:

答案 0 :(得分:2)

发生这种情况的原因是iframe采用ajaxSubmit后备策略。我认为,自从响应被发布到iframe IE尝试找出如何解决它并决定它要求您下载响应而不是仅仅将其放入iframe

前一段时间我遇到过同样的情况,发现了一篇提供解决方法的文章(我现在找不到)。

如果textarea 中包围您的json响应,则没有人会抱怨(IE,FF,Chrome,可能是Safari),您将正确解析您的响应。

E.g。如果你要回来了

{Id: 1, Name: 'Me'}

回来:

<textarea>{Id: 1, Name: 'Me'}</textarea>

你现在看到IE认为它是html所以它将它插入隐藏的iframe。您的ajaxSubmit函数仍然被调用并正确解析json,然后每个人都很高兴。 :)

如果你正在使用ASP.NET MVC,你可以无耻地复制这个扩展方法:)

public static class ControllerExtensions
{
    public static ActionResult JsonSafe(this IController controller, object obj)
    {
        JavaScriptSerializer serializer = new JavaScriptSerializer();
        return new WriteResult(string.Format("<textarea>{0}</textarea>", serializer.Serialize(obj)));
    }
}

答案 1 :(得分:1)

关于XMLHttpRequest的维基百科文章似乎很好地概述了XMLHttpRequest背后的历史。似乎Microsoft和Mozilla开发/采用了自己的对象版本,因此您可能会看到不同的属性。

以下是Microsoft XMLHttpRequest interface members实施的链接,它似乎与您的提醒中的属性相匹配。

以下是Mozilla实施XMLHttpRequest的链接。

因此,当我们等待W3C到standardize XMLHttpRequest时,您将继续在浏览器中实现不同的实现,就像您在这种情况下看到的那样。

对于一些额外的乐趣,这里有关于XMLHttpRequest的Apple'sOpera's规范。