值得注意的是:以下内容是通过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;
}
我在控制台和提琴手中看到的错误轮询实际上正在发生,但每次轮询都会发生相同的失败:
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 为 null 或不是对象")。 我知道该对象为空,我不明白的是为什么它是空的。
........
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!! ***
});
.........
根据这个答案,我不相信IE8支持XMLHttpRequest()
对象或XDomainRequest()
的.addEventListener()
方法(或大多数其他方法,它似乎是后来添加的)。
尝试将代码的该部分重写为:
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不支持它。
IE8 和更少的使用 attachEvent ...但它不适用于XMLHttpRequest
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener#Compatibility
当对JS的某些问题有疑问时,首先停止MDN,否则:)