6

值得注意的是:以下是通过 https 跨域完成的。老实说,我认为这不是问题,因为在 IE10、Chrome 和 FF 中一切正常。我的猜测是它可能是 IE8 中的 XDomainRequest 对象差异?不过不确定。

下面sendLoginRequest的方法是最先调用的方法。下面还提供了所有其他支持代码。

这一切都非常简单,但不知道为什么 IE8 会失败。

function WrappedSocket(data, session_string) {
    var clientSocket = io.connect('https://xxxxxxxx/socketio', { query: "session=" +       encodeURIComponent(session_string), transports: ['jsonp-polling'] });
    clientSocket.socket.on("connect", function () { console.log("CONNECT_SUCCEED"); });
    clientSocket.socket.on("connect_failed", function () { console.log("CONNECT_FAILED");    });
    clientSocket.socket.on("reconnect_failed", function () {    console.log("RECONNECT_FAILED"); });
    clientSocket.socket.on("error", function (eobj) { console.log("Socket error " + eobj);    });
    console.log("Made a socket that is talking");
}

var my_socket;


function set_up_socket(data, sessionString) {
    setSession(data.responseText);
    my_socket = new WrappedSocket(data, sessionString);
    my_socket.socket.emit("message", "Howdy!");
}

function sendLoginRequest(loginCode, nextRequest) {
    var xhr = createCORSRequest('POST', 'https://xxxxx/login', false);
    var sessionString = 'xxxx';

    if ("withCredentials" in xhr) {
        xhr.addEventListener("load", function () {
            set_up_socket(this, sessionString);
        }, false);
    }
    else {
        xhr.onload = function () {
            set_up_socket(this, sessionString);
        };
    }

    xhr.send();
    }

function createCORSRequest(method, url, onload) {
    xhrObj = new XMLHttpRequest();
    if ("withCredentials" in xhrObj) {
        // Check if the XMLHttpRequest object has a "withCredentials" property.
        // "withCredentials" only exists on XMLHTTPRequest2 objects. 
        if (onload) {
            xhrObj.addEventListener("load", onload, false);
        }
        xhrObj.open(method, url, true);
        xhrObj.withCredentials = true;
    } else if (typeof XDomainRequest != "undefined") {
        // Otherwise, check if XDomainRequest.
        // XDomainRequest only exists in IE, and is IE's way of making CORS requests.

        xhrObj = new XDomainRequest();
        xhrObj.open(method, url);
        if (onload) {
            xhrObj.onload = onload;
        }
    } else {
        // Otherwise, CORS is not supported by the browser.
        xhrObj = null;
    }
    return xhrObj;
    }

我在控制台和 Fiddler 轮询中看到的错误实际上正在发生,但每次轮询都会发生相同的故障:

LOG:CONNECT_FAILED
'f.parentNode' is null or not an object
'f.parentNode' is null or not an object
LOG:CONNECT_FAILED
'f.parentNode' is null or not an object
'f.parentNode' is null or not an object
LOG:CONNECT_FAILED
'f.parentNode' is null or not an object
'f.parentNode' is null or not an object
LOG:CONNECT_FAILED
'f.parentNode' is null or not an object
'f.parentNode' is null or not an object
LOG:CONNECT_FAILED
'f.parentNode' is null or not an object
'f.parentNode' is null or not an object
LOG:CONNECT_FAILED
'f.parentNode' is null or not an object
'f.parentNode' is null or not an object

…………

(你明白了,这在它轮询时一遍又一遍地发生。)

同样,您可以看到每个请求一个接一个地触发,来自服务器的所有 200 个响应,但都导致来自 socket.io.js 文件的 CONNECT_FAILED 和 JS 错误。

最后,这是客户端上 socket.io.js 文件中的代码,该代码与上面控制台屏幕截图中看到的错误(“f.parentNode 为空或不是对象”)有关。我知道对象是空的,我不明白为什么它是空的。

........

if (this.isXDomain() && !io.util.ua.hasCORS) {
  var insertAt = document.getElementsByTagName('script')[0]
    , script = document.createElement('script');

  script.src = url + '&jsonp=' + io.j.length;
  insertAt.parentNode.insertBefore(script, insertAt);

  io.j.push(function (data) {
      complete(data);
      script.parentNode.removeChild(script);  // *** BREAKS HERE!! ***
  });

.........
4

2 回答 2

1

根据这个答案,我不相信 IE8 支持对象或对象的.addEventListener()方法(或大多数其他方法,它似乎是后来添加的)。XMLHttpRequest()XDomainRequest()

尝试将那部分代码重写为:

xhr.onload=function () {
        set_up_socket(this, sessionString);
    };

如果您想为其他现代浏览器保持相同的语法,您可以通过将其包装在条件中来回填:

if(typeof xhr.addEventListener === undefined)
{
    xhr.onload=function () {
        set_up_socket(this, sessionString);
    };
}

不知道它是否能解决问题,但可能会有所帮助。

MDN 表示:“包括 Firefox 在内的最新浏览器除了将 on* 属性设置为处理函数外,还支持通过标准 addEventListener API 监听 XMLHttpRequest 事件。” . 同样,我不确定,因为他们没有说哪些浏览器以及何时,但最好我可以告诉 IE8 不支持它。

于 2013-09-13T15:11:01.050 回答
0

IE8 和 less 使用 attachEvent ...但它不适用于 XMLHttpRequest

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener#Compatibility

如果对 JS 的某些问题有疑问,请先停止 MDN,然后再停止 :)

于 2013-09-17T22:00:43.843 回答