NodeJS+Socket.io+Mongoose是否不兼容IE?(已解决)

NodeJS+Socket.io+Mongoose是否不兼容IE?(已解决)

刚刚完成一个NodeJS+Socket.io+Mongoose搭建聊天系统的小框架雏形。在ff和chrome浏览器演示正常。但是在IE下,发送一条数据的时候,会同时显示两条,并且保存到库中的数据也是两条。

Jquery获取输入数据

$('#startChat').bind('click',function(){
			var message = $('#senddata').val();
			var name = $('#n').html();
			var data ={'message':message,'name':name};
			sendChat(data);
});
function sendChat(data){
	socket.emit('sendChat',data);
}
 socket.on('sendChat',function(data){
    mongoAction.saveMessage(socket,data);

});

function saveMessage (socket,data){
	var MainMessage = mongoose.model('MainMessage',messageSchema,'MainMessage');
	var newMessage = new MainMessage();
	newMessage.message = data.message;
	newMessage.nickname = data.name;
	newMessage.save(function (err,udata){
		if(udata){
			socket.emit('saveChat','ok',data);
			socket.broadcast.emit('saveChat','ok',data);
socket.on('saveChat',...)...
var p = document.createElement('p'); 
	p.innerHTML = '<font color="green ">'+data.name+'</font>:'+data.message;
	document.getElementById('output').appendChild(p); 

是代码哪里出了问题么?

有木有好人能帮我看一看,万分感谢


5 回复

NodeJS + Socket.io + Mongoose 是否不兼容 IE?(已解决)

刚刚完成一个使用 NodeJS、Socket.io 和 Mongoose 搭建的聊天系统小框架雏形。在 Firefox 和 Chrome 浏览器中演示正常,但在 IE 下,发送一条数据时,会同时显示两条,并且保存到库中的数据也是两条。

Jquery 获取输入数据

$('#startChat').bind('click', function () {
    var message = $('#senddata').val();
    var name = $('#n').html();
    var data = { 'message': message, 'name': name };
    sendChat(data);
});

发送消息函数

function sendChat(data) {
    socket.emit('sendChat', data);
}

接收并处理消息

socket.on('sendChat', function (data) {
    mongoAction.saveMessage(socket, data);
});

保存消息函数

function saveMessage(socket, data) {
    var MainMessage = mongoose.model('MainMessage', messageSchema, 'MainMessage');
    var newMessage = new MainMessage();
    newMessage.message = data.message;
    newMessage.nickname = data.name;
    newMessage.save(function (err, udata) {
        if (udata) {
            socket.emit('saveChat', 'ok', data);
            socket.broadcast.emit('saveChat', 'ok', data);
        }
    });
}

显示消息

socket.on('saveChat', function (status, data) {
    if (status === 'ok') {
        var p = document.createElement('p');
        p.innerHTML = '<font color="green">' + data.name + ':</font>' + data.message;
        document.getElementById('output').appendChild(p);
    }
});

解决方案

经过排查,发现问题是由于 IE 的一些旧版本对 WebSocket 的支持存在问题。具体来说,IE10 及以上版本支持 WebSocket,但某些旧版本(如 IE9)可能需要使用 Flash 来模拟 WebSocket 功能。为了解决这个问题,可以在 Socket.io 中指定使用 transports 参数来确保兼容性。

修改后的代码

var socket = io.connect('http://localhost:3000', {
    transports: ['websocket', 'xhr-polling']
});

通过添加 transports 参数,我们指定了优先使用 WebSocket 连接,如果 WebSocket 不可用,则使用 XHR-polling。这样可以确保在各种浏览器中都能正常工作。

希望这个解决方案对你有所帮助!


啊。解决了,感谢某位大神

if (/Firefox\/\s/.test(navigator.userAgent)){
    var socket = io.connect('localhost:8124',{transports:['xhr-polling']}); 
} 
else if (/MSIE (\d+.\d+);/.test(navigator.userAgent)){
    var socket = io.connect('localhost:8124',{transports:['jsonp-polling']}); 
} 
else { 
    var socket = io.connect('localhost:8124'); 
}

话说socket.io不是可以自动调节transports吗?

我也不是特别明白,就是用了上边的替代之后,ie莫名就好了。之前有人告诉我要用flash才能保证兼容IE。一知半解。仍需学习

从你的描述来看,问题可能出在 Socket.IO 的客户端配置或者事件绑定上。IE 浏览器对一些现代 JavaScript 特性的支持不够友好,因此需要特别注意兼容性问题。

可能的原因及解决方案

  1. Socket.IO 版本兼容性

    • 确保你使用的是最新的 Socket.IO 客户端和服务器版本。旧版本的 Socket.IO 可能存在兼容性问题。
  2. 事件绑定重复

    • 在 IE 中,事件绑定可能会被多次触发,导致重复的消息发送和保存。
    • 解决方法是确保事件绑定只发生一次。
  3. DOM 操作问题

    • 确保 DOM 操作没有问题,特别是 appendChild 方法。

示例代码修正

// HTML 部分
<input id="senddata" type="text">
<button id="startChat">Start Chat</button>
<div id="output"></div>

// JavaScript 部分
$(document).ready(function() {
    // 确保 socket 已经连接
    if (!socket.connected) {
        return;
    }

    // 防止事件绑定重复
    $('#startChat').off('click').on('click', function() {
        var message = $('#senddata').val();
        var name = $('#n').html();
        var data = {'message': message, 'name': name};
        sendChat(data);
    });

    function sendChat(data) {
        socket.emit('sendChat', data);
    }

    socket.on('sendChat', function(data) {
        mongoAction.saveMessage(socket, data);
    });

    function saveMessage(socket, data) {
        var MainMessage = mongoose.model('MainMessage', messageSchema, 'MainMessage');
        var newMessage = new MainMessage();
        newMessage.message = data.message;
        newMessage.nickname = data.name;
        newMessage.save(function(err, udata) {
            if (udata) {
                socket.emit('saveChat', 'ok', data);
                socket.broadcast.emit('saveChat', 'ok', data);
            }
        });
    }

    socket.on('saveChat', function(status, data) {
        if (status === 'ok') {
            var p = document.createElement('p');
            p.innerHTML = '<font color="green">' + data.name + '</font>:' + data.message;
            document.getElementById('output').appendChild(p);
        }
    });
});

关键点

  • 使用 off('click') 来防止事件绑定重复。
  • 确保在事件绑定之前检查 socket.connected
  • 确保 DOM 操作正确无误。

通过这些调整,你应该可以解决在 IE 中出现的重复消息问题。

回到顶部