【问题标题】:Fall-back support for XMLHTTPRequest对 XMLHTTPRequest 的回退支持
【发布时间】:2015-12-19 19:04:21
【问题描述】:

我们有一个 Web 应用程序,它使用本机 XMLHttpRequest() 将数据发送回我们的服务器。我们的一个较大客户的用户似乎在 Win7(64 位)中运行 IE8,并且在他们的浏览器中禁用了“启用本机 XMLHTTP 支持”。

我们已经实现了实例化 ActiveXObject 来代替 XMLHttpRequest 的典型场景,以便尝试在 IE6(不支持原生 XMLHTTP;是的,我们仍然有客户端在瘦客户端上运行它!)如果此复选框选项已关闭,我希望 IE8 可以用作后备。但是,一旦创建了一个对象,在其上调用open() 方法时就会出现类型错误。

这是我的代码:

// Posts back an xml file synchronously and checks for parse error.
// Returns xml object or null.  Used in RSUserData.
XML.PostXmlFile = function(sURL, doc)
{
    try
    {
        // Validate Input
        if ((typeof (sURL) != "string") || (sURL == ""))
            return null;

        if (window.XMLHttpRequest)  // IE7+, FF and Chrome
        {
            // Mozilla, create a new DOMParser and parse from string
            // Although IE9 and IE10 can successfully load XML using this block, it can't use document.evaluate nor selectNodes/selectSingleNode to navigate it
            // Ref: http://msdn.microsoft.com/en-us/library/ie/ms535874(v=vs.85).aspx
            // Ref: http://msdn.microsoft.com/en-us/library/ie/ms534370(v=vs.85).aspx
            // Ref: http://blogs.msdn.com/b/ie/archive/2012/07/19/xmlhttprequest-responsexml-in-ie10-release-preview.aspx
            var req = new XMLHttpRequest();
            req.open("post", sURL, false);
            req.send(doc);
            if (req.status != 200)
                throw { message: 'HTTP Post returned status ' + req.status + ' (' + req.statusText + ') when sending to ' + sURL };

            // IE11+:   req.responseXML returns a native XML Document
            // IE9/10:  req.responseXML returns an IXMLDOMDocument2 object but we can convert req.responseText to native XML using DOMParser
            // IE6/7/8: req.responseXML returns an IXMLDOMDocument2 object but DOMParser is not available

            if (window.DOMParser)
            {
                var parser = new DOMParser();
                return parser.parseFromString(req.responseText, 'application/xml');
            }
            else
                return req.responseXML;     // NATIVE
        }
        else
        {
            // up to IE6:
            // Ref: http://blogs.msdn.com/b/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
            var oXML = XML.GetActiveX_XML();
            if (!oXML)
                throw { message: "Could not instantiate an Msxml2 ActiveXObject", innerException: e };

            oXML.open('POST', sURL, true);
            oXML.send(sFile);
            if (oXML.parseError.errorCode == 0)
            {
                xmlDoc = oXML;
                return xmlDoc;
            }
            return null;
        }

    }
    catch (e)
    {
        var s = "Exception in XML.PostXmlFile(). " + (e.message ? e.message : "");
        throw { message: s, innerException: e };
    }
}


XML.GetActiveX_XML = function()
{
    var progIDs = ['Msxml2.DOMDocument.6.0', 'Msxml2.DOMDocument.3.0'];
    for (var i = 0; i < progIDs.length; i++)
    {
        try
        {
            var oXML = new ActiveXObject(progIDs[i]);
            var sl = oXML.getProperty("SelectionLanguage");
            if (sl !== "XPath")
                oXML.setProperty("SelectionLanguage", "XPath"); // Changes v3.0 from XSLPattern to XPath

            var ns = "xmlns:rs='" + XML._nsResolver('rs') + "' xmlns:xsi='" + XML._nsResolver('xsi') + "'";
            //          ns = "xmlns:na='http://myserver.com' xmlns:nb='http://yourserver.com'";
            oXML.setProperty("SelectionNamespaces", ns);
            return oXML;
        }
        catch (ex) { }
    }
    return null;
}

注意事项:

  • 目的是使用 url 和有效负载调用 XML.PostXmlFile()
  • 现代浏览器按预期使用new XMLHttpRequest()
  • IE6 预计使用XML.GetActiveX_XML(),因为window.XMLHttpRequest 返回falsey
  • 禁用“启用本机 XMLHTTP 支持”的 IE8 进入 IE6 代码(因为 window.XMLHttpRequest 返回 falsey)但实例化对象失败,因为它不支持 open() 方法(oXML.open('POST', sURL, true);)李>

当“启用本机 XMLHTTP 支持”被禁用时,我有什么方法可以使用 IE8 发回我的有效负载?

【问题讨论】:

  • 你可以使用老式的
    标签吗?我没有看到任何现代的东西不适合一种形式(数据方面)
  • 您是否也尝试过使用字符串"Microsoft.XMLHTTP"?例如:var progIDs = ['Microsoft.XMLHTTP', 'Msxml2.DOMDocument.6.0', 'Msxml2.DOMDocument.3.0'];。如果我没记错的话,当原生 XMLHTTP 被禁用时,你必须使用最现代的可用 ActiveX 对象。
  • @dandavis 不幸的是,这里不能选择提交表单,因为示例已简化并且是更大流程的一部分。
  • @Buzinas 我确实以这种方式尝试了该对象,但是当未选中该复选框时,IE8 无法完全实例化该对象(抛出异常并循环到数组中的下一个命名对象)。我的猜测是 IE8 对待"Microsoft.XMLHTTP" 的方式与原生 XMLHTTP 完全相同。谢谢。
  • @Buzinas 抱歉,"Microsoft.XMLHTTP" 对象 确实 实例化,但是下一行中的 getProperty() 方法抛出 "对象不支持此属性或方法” 异常。我需要该代码来处理传入/传出 xml 有效负载中的名称空间。谢谢。

标签: javascript ajax xmlhttprequest msxml


【解决方案1】:

您应该先查看Microsoft.XMLHTTP 是否可用,然后再检查是否有XMLHttpRequest

var bActiveX;

try {
  new ActiveXObject('Microsoft.XMLHTTP');
  bActiveX = true;
}
catch(e) {
  bActiveX = false;
}

然后,检查您的if 条件:

if (window.XMLHttpRequest || bActiveX) { // IE7+, FF and Chrome
  var req = XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');

  /* the rest of your code */
}

【讨论】:

  • 太棒了!谢谢你指出这一点。我将“本机 XMLHTTP 支持”与“任何与 ActiveX 控件相关的内容”分开。您已经指出 ActiveXObject('Microsoft.XMLHTTP') 提供了本机 XMLHTTP 的替代品,并且其他方法(例如 IE6 使用的方法)的处理方式不同。再次感谢。
猜你喜欢
  • 2017-04-18
  • 1970-01-01
  • 2012-07-02
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2012-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多