千家信息网

如何使用JavaScript与Node.js打造一款聊天App

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章将为大家详细讲解有关如何使用JavaScript与Node.js打造一款聊天App,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。聊天是我们人与
千家信息网最后更新 2026年11月02日如何使用JavaScript与Node.js打造一款聊天App

这篇文章将为大家详细讲解有关如何使用JavaScript与Node.js打造一款聊天App,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

聊天是我们人与人交流最直接的方式,互联网的加入使我们交流更加便捷。我们手机上的微信、QQ是我们手机必不可少的应用软件。那么,我们是否可以做一款聊天应用呢?

之前我自己闲着没事,研究过一些技术,做了一款即时通讯应用,下面我将选取几幅具有代表性的图片供大家参考。

一、应用示图

以上是这款应用的主要页面,功能可能相对简陋点,不过基本的功能已经实现了,下面我将给出核心代码,全部源码地址在文末。

二、部分核心源码

前台主要核心逻辑:

这里我只列举了js核心代码,查看完整代码可以去文末。

function sock() {     return io.connect("http://localhost:3003"); // http环境下 } // 心跳机制 document.addEventListener('visibilitychange', function () {     if (document.visibilityState == 'hidden') {         //记录页面隐藏时间         sock()         console.log('隐藏了')     } }) setInterval(() => {     sock() }, 10000); var socket = sock() var re = document.querySelector("#re"); var register1 = document.querySelector(".register"); var init = document.querySelector(".init"); var passr = document.querySelector("#passr"); var passl = document.querySelector("#passl"); var login1 = document.querySelector(".login"); var register_b = document.querySelector("#register_b"); var lo = document.querySelector("#lo"); var chat = document.querySelector("#chat"); var login_b = document.querySelector("#login_b"); var myMes = ""; var vf = ""; var na = ""; var p = ""; var we = ""; var div = ""; var v = ""; var q = 0; var regCn = /[@:]/im; var pattern = /^[\u4E00-\u9FA5]{1,5}$/; // 同意 document.querySelector('.yes').onclick=function () {     document.querySelector('.dark').style.display='none' } document.querySelector('.ys').onclick = function () {     document.querySelector('.dark').style.display = 'block' } // 初始页面注册 document.querySelector("#reg").onclick = function () {     register1.style.display = "block";     init.style.display = "none";     document.querySelector(".bg").style.display = "none"; } // 初始页面登录 document.querySelector("#log").onclick = function () {     login1.style.display = "block";     init.style.display = "none";     document.querySelector(".bg").style.display = "none"; } // 登录按钮 login_b.onclick = function () {     login();  } // 注册按钮 register_b.onclick = function () {     register(); } //发送 document.getElementById("btn").onclick = function () {     send(); }; // 内容填充 document.getElementById("text").onkeyup = function () {     if (document.getElementById("text").value.length != 0) {         document.getElementById("btn").style.cssText = "background:#98E165;color:#fff;"     } else {         document.getElementById("btn").style.cssText = "background: #DDDEE2;color:#fff"     } } document.querySelector("#text").onclick = function () {     document.querySelector('#text').scrollIntoView(false); } // 传名 var users2 = ""; socket.on('users', function (users) {     users2 = users;     //  console.log(users2); }); // 传密码 var pass2 = "" socket.on('pass', function (val) {     pass2 = val;     //  console.log(pass2) }); // 统计在线人数 var arrh = [] socket.on('dataval', function (val) {     vf = val;     console.log(vf);      for (let i = 0; i < vf.length; i++) {         // uu++         arrh.push(vf[i])         console.log(arrh)     }     var rf = [...new Set(arrh)]     console.log(rf)     rf = vf     for (let j = 0; j < rf.length; j++) {         var li = document.createElement("li");         li.classList.add("active");         li.innerText = rf[j]         console.log(rf[j])         socket.emit("time", rf[j]);         document.querySelector(".fix").appendChild(li);      } }); socket.on('join', function (val) {     document.querySelector(".fix")[xss_clean] = '' }) socket.on('disconnect', function (val) {     console.log('离开了')     document.querySelector(".fix")[xss_clean] = '' }) // 生成数组 var ar = ""; socket.on('array', function (val) {     ar = val;     // console.log(ar); }); // 封装注册 function register() {     if (re.value.length == 0) {         sweetAlert("请输入用户名!");         return false;     } else if (regCn.test(re.value)) {         sweetAlert("格式错误,不能够用和:符号取名,请重新输入!");         return false;     } else if (pattern.test(re.value)) {         sweetAlert("不能使用中文字符哦!");         return false;     } else if (!(re.value.length == 0 && regCn.test(re.value))) {         if (users2.indexOf(re.value) != -1) {             sweetAlert("已经注册啦,换一个用户名吧!");         } else {             names(re.value.trim());             pass(passr.value.trim());             sweetAlert("注册成功,您的用户名:" + re.value.trim());             document.querySelector(".swal-button").onclick = function () {                 _window.location.reload();             }         }     } } //移动端使用touchend var event = navigator.userAgent.match(/(iPhone|iPod|Android|ios)/i) ? 'touchend' : 'click';  // 选择器 var Q = function (id) {     return document.getElementById(id) }; //右 var _right = new mSlider({     dom: ".layer-right",     direction: "right" });  Q("btnRight").addEventListener(event, function (e) {     _right.open(); }) // 封装登录 function login() {     if (lo.value.length == 0) {         sweetAlert("请输入用户名!");         return false;     } else if (regCn.test(lo.value)) {         sweetAlert("格式错误,不能够用和:符号取名,请重新输入!");         return false;     } else if (pattern.test(lo.value)) {         sweetAlert("不能使用中文字符哦!");         return false;     } else if (!(lo.value.length == 0 && regCn.test(lo.value))) {         if (users2.indexOf(lo.value) != -1) {             for (var i = 0; i < users2.length; i++) {                 if (users2[i] === lo.value && pass2[i] === passl.value) {                     if (ar.indexOf(lo.value) == -1) {                         sweetAlert("恭喜您,登录成功!");                         socket.emit('setName', lo.value.trim());                         names1(lo.value.trim());                         login1.style.display = "none";                         document.querySelector(".bg").style.display = "none";                         document.querySelector(".cd span").style.display = "none";                         document.querySelector(".title img").style.display = "block";                         document.querySelector(".fix").style.display = "block";                         document.querySelector(".title").style.display = "block";                          _right.open();                         document.querySelector(".swal-button").onclick = function () {                             document.getElementById("text").focus();                             document.querySelector(".fix").addEventListener('click', function (e) {                                 if (e.target.nodeName === "LI" && e.target.innerText != document.title) {                                     _right.close();                                     document.querySelector(".chat_b").style.display = "block";                                     document.querySelector(".box").style.display = "block";                                     document.querySelector(".tit").innerText = e.target.innerText;                                     document.querySelector(".ys").style.display="none";                                     document.querySelector("#text").focus();                                     onOff = true;                                 } else {                                     sweetAlert("不能跟自己聊天哦~");                                 }                             })                         }                     } else {                         sweetAlert("不能重复登录哦!");                         return                     }                 }                 if (users2[i] === lo.value && pass2[i] != passl.value) {                     sweetAlert("密码错误!");                     return;                 }             }         } else {             sweetAlert("请先注册哦!");             login1.style.display = "none";             register1.style.display = "block";         }     } } // 传名 function names(value) {     this.name = value;     socket.emit("reg", name); }  function names1(value) {     this.name1 = value;     socket.emit("join", name1);     document.title = name1 } // 传密码 function pass(value) {     socket.emit("pass", value); } socket.on("join", function (user) {     this.na = user; }) socket.on("reg", function (user) {     this.na1 = user; }) // 私发消息 socket.on('message1', function (data) {     var p1 = document.createElement("div");     var s1 = document.createElement("p");     var s2 = document.createElement("p");     var div1 = document.createElement("div");     var em = document.createElement("em");     var ads = document.createElement("audio");     ads.src = "https://www.maomin.club/data/res.mp3";     ads.className = "ads";     s1.className = "chatlist";     s2.className = "chatlist1";     em.className = "zwasked1";     div1.className = "divbox";     s1.innerText = data.from;     s2.innerText = data.msg;     s1.appendChild(em);     p1.appendChild(s1);     p1.appendChild(s2);     chat.appendChild(ads);     ads.play();     div1.appendChild(p1);     chat.appendChild(div1);     chat.scrollTop = chat.scrollHeight; }); // 私聊发送 function send() {     if (document.getElementById("text").value != "") {         socket.emit('sayTo', {             from: lo.value,             to: document.querySelector(".tit").innerText,             msg: document.querySelector("#text").value,         })         var p1 = document.createElement("div");         var s1 = document.createElement("p");         var s2 = document.createElement("p");         var em = document.createElement("em");         var div1 = document.createElement("div");         var ads = document.createElement("audio");         p1.style.cssText = "float:right;";         s2.style.cssText = "color:#333;"         ads.src = "https://www.maomin.club/data/s.wav";         ads.className = "ads";         div1.className = "divbox";         s1.className = "chatlist";         s1.style.cssText = "color:#333 !important;float:right; !important";         s2.className = "chatlist2";         em.className = "zwasked";         s1.innerText = lo.value;         s2.innerText = document.querySelector("#text").value;         s1.appendChild(em);         p1.appendChild(s1);         p1.appendChild(s2);         chat.appendChild(ads);         ads.play();         div1.appendChild(p1);         chat.appendChild(div1);         chat.scrollTop = chat.scrollHeight;     } else {         sweetAlert('请输入内容!');     }     chat.scrollTop = chat.scrollHeight;     document.querySelector("#text").value = "";     document.querySelector("#text").focus(); }

后台主要核心逻辑:

我这里只列举了http环境的,完整代码中有https环境的。

var http=require("http"); var fs=require("fs"); var express = require('express'); var ws=require("socket.io"); var path=require("path"); var _ = require('underscore'); var usocket = []; var usocket1 = []; var pass=[]; var data=[]; var hashName = {}; var onlineCount = 0; var app = express(); // 静态文件识别 app.use(express.static(path.join(__dirname, './public'))); var server=http.createServer(function (req,res) {     var filename = req.url.split('/')[req.url.split('/').length-1];     var suffix = req.url.split('.')[req.url.split('.').length-1];     if(req.url==='/'){         res.writeHead(200, {'Content-Type': 'text/html'});         var html = fs.readFileSync("./public/index.html");         res.end(html)     }else if(suffix==='css'){         res.writeHead(200, {'Content-Type': 'text/css'});         res.end(get_file_content(path.join(__dirname, 'public', 'css', filename)));     }else if(suffix==='js') {         res.writeHead(200, {'Content-Type': 'text/javascript'});         res.end(get_file_content(path.join(__dirname, 'public', 'js', filename)));     }else if (suffix in ['gif', 'jpeg', 'jpg', 'png']) {         res.writeHead(200, {             'Content-Type': 'image/' + suffix         });         res.end(get_file_content(path.join(__dirname, 'public', 'images', filename)));     } }); function get_file_content(filepath) {     return fs.readFileSync(filepath); } // 获取在线 function broadcast() {     io.sockets.emit("dataval", hashName); } //提供私有socket function privateSocket(toId) {     return (_.findWhere(io.sockets.sockets, {         id: toId     })); } // 封装删除 function removeByValue(arr, val) {     for (var i = 0; i < arr.length; i++) {         if (arr[i] == val) {             arr.splice(i, 1);             break;         }     } } // 连接socket var io=ws(server); io.on("connection",function(socket){ // 写入成功后读取测试 fs.readFile('./user.xls', 'utf-8', function (err, data) {     if(data!=null){     var value = data.split('\n');      io.sockets.emit("users", value);       }  }); // 写入成功后读取测试 fs.readFile('./password.xls', 'utf-8', function (err,data) {     if(data!=null){     var pass1=data.split('\n');     io.sockets.emit("pass", pass1);     } });     broadcast(); // 生成名字 socket.on('setName', function (data) {     var name = data;     hashName[name] = socket.id;     // console.log(hashName[name]);     broadcast(); }); // 私聊发送 socket.on('sayTo', function (data) {     var toName = data.to;     var toId;     console.log(toName);     if (toId = hashName[toName]) {         privateSocket(toId).emit('message1', data);     } }); // 离开 socket.on('disconnect', function (name) {          name=this.i2;          io.emit("disconnect", name);          removeByValue(data, name);          io.sockets.emit("dataval", data);     }) // 在线 socket.on('time', function (val) {         // console.log(val);    }) // 注册 socket.on("reg", function (name) {           usocket[name] = socket;           this.i1=name;           io.emit("reg", name);           var myname =this.i1+"\n";           fs.writeFile('./user.xls', myname, {               'flag': 'a'           }, function (err) {               if (err) {                   throw err;               }               // 写入成功后读取测试               fs.readFile('./user.xls', 'utf-8', function (err,data) {                   if (err) {                       throw err;                   }               });           });     }) // 加入 io.emit('connected', ++onlineCount);     // console.log(data);     io.sockets.emit("array", data);     socket.on("join", function (name) {         usocket1[name] = socket;         this.i2 = name;         io.emit("join", name);         data.push(name);         io.sockets.emit("dataval", data);     }) // 密码 socket.on("pass",function(val){       pass[val]=socket;       this.i2=val;       io.emit("pass", val);       var password=this.i2+"\n";        fs.writeFile('./password.xls', password, {               'flag': 'a'           }, function (err) {               if (err) {                   throw err;               }           });     }) }); server.listen(3003); console.log("服务器运行中");

三、源码地址

这个项目是之前写的,欢迎大家进行指正。大家可以复制下面的源码地址,拉取下来就可以在本地实现一个聊天服务。如果你有服务器可以把它部署在服务器上,这样你就可以有一个属于自己的聊天App了。大家可以根据源码进行学习,有不明白的可以随时问我。

https://github.com/maomincoding/chat3

关于如何使用JavaScript与Node.js打造一款聊天App就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

成功 源码 应用 登录 输入 代码 内容 密码 核心 用户 用户名 页面 服务 地址 服务器 环境 错误 在线 封装 测试 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州万易互联网科技有限公司 互联网科技工作委员会主任 中国互联网科技工作委员会毛军 圆梦互联网科技 互联网科技卖菜 互联网科技上市公司 须眉科技是互联网公司吗 赶超互联网科技 微信多开 互联网科技产业特征 互联网科技扶贫时间 中国科技创新与世界互联网大会 洛阳共同富裕互联网科技有限公司 广东工业互联网大赛深圳学泰科技 城市宝互联网科技有限公司 江苏互联网智能科技软件 互联网风格科技公司名称 昆明中奇联合互联网科技 陕西彩京云互联网科技有限公司 恒生互联网科技趋势 如何强化互联网金融科技 与互联网科技公司 移动互联网科技股 互联网大会黑科技排名 工业互联网展湾科技股份有限公司 每天都有哪些好的互联网科技 工业互联网科技成果转化 吉林省码上互联网科技电话 江苏互联网智能科技产品出厂价 悟空问答互联网科技 互联网科技大佬云集
0