昨天我们花了大部分时间试图解决这个问题。因此,作为最后的努力,我在这里发布。
我们的设置是 Node.js/Express 后端。 Socket.io 与 Express 位于同一端口。
app.io = io.listen(server);
app.io.set('origin', '*');
app.io.set('log level', '2');
app.io.enable('browser client minification');
app.io.set('transports', [
'websocket',
'flashsocket',
'htmlfile',
'xhr-polling',
'jsonp-polling'
]);
我已明确启用所有传输。我们希望 jsonp 或 flash 套接字能够在我们最不喜欢的浏览器上正常运行......
但是,我想他们是我们最不喜欢的人是有原因的。 ;-)
客户端我们有一个带有 socket.io 的 Angularjs 应用程序。非常松散地基于 this tutorial
window.WEB_SOCKET_SWF_LOCATION = 'https://api.ourdomain.com/socket.io/static/flashsocket/WebSocketMain.swf';
var socket = io.connect('https://api.ourdomain.com', {
'reconnect' : true,
'reconnection delay' : 1500
});
我们尝试添加 here 所示的 SWF 位置以使 flashsockets 正常工作。它正在提供策略并获取文件。所以运气不好。
无论如何,在 ie7-9 上,当它尝试通过 jsonp 轮询进行连接时,我们会收到此错误:
对象不支持此属性或方法
jsonp 消息的内容将如下所示:
io.j[1]("1::");
有时会包含更多内容。
io.j 似乎在主 socket.io.js 文件中设置为数组。
当我将其放入开发人员工具控制台时,它会抛出相同的错误。
我尝试将所有元标记移到脚本之前,如建议的 here 。这并没有改变任何事情。
XHR 轮询似乎也不起作用。我们已经看到了一些关于更改 ie 设置的帖子。但显然我们不能要求我们的客户仅仅为了访问我们的网站而要求他们的 IT 部门更改他们的浏览器设置。所以我们放弃了这种方法。
还尝试创建一个空白页面并连接..这有效。那么什么会干扰呢?
希望你们有什么东西?
最佳答案
我们无法通过简单地使 Socket.io 工作来解决此问题。我不知道这是 Socket.io 的问题还是 Angularjs 和 Socket.io 的组合。
不过,我们确实通过添加自己的后备解决了这个问题。在我们的 Socket.io 服务中,我们检查 ie9+ 以及 webkit 和 firefox 浏览器中是否存在某个功能。
var use_socketIO = true;
/*
I'd like to detect websocket, or jsonp.
But those transport methods themselves work.
Just not reliably enough to actually use
*/
if (typeof(window.atob) === 'undefined') {
console.log('browser appears to be < ie10.');
use_socketIO = false;
}
if (use_socketIO) {
var socket = io.connect('https://api.ourdomain.com', {
'reconnect' : true,
'reconnection delay' : 1500
});
}
// Fall back http method.
function httpReq(method, url, data) {
var defer = $q.defer();
$http({
method: method,
url: '//www.domain.com/api'+url,
data: data
}).success(function (data, status, headers, config) {
defer.resolve(data)
});
return defer.promise;
}
// Socket.io method.
function socketReq(method, url, data) {
var defer = $q.defer();
socket.emit(method, {url: url, data: data}, function (response) {
try {
var data = JSON.parse(response);
defer.resolve(data);
} catch (e) {
$log.error('Failed to parse JSON');
$log.info(response);
defer.reject(e);
}
});
return defer.promise;
}
// Main Request method
function request(method, url, data) {
if (use_socketIO) {
return socketReq(method, url, data || {});
} else {
return httpReq(method, url, data || {});
}
}
然后我们只需调用 request('get', '/url');
服务器端我们做了一些魔法来构建一个 req 和 res 对象(如果它是 Socket.io),然后将其转发给express来处理,否则express只是像平常一样处理它。
关于javascript - Socket.io IE7-9 JSONP 轮询错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21188361/