开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第35天,点击查看活动详情、
node 是我们前端程序员强大的服务工具,现在其不仅可以完成我们前端大部分的文件操作,本地服务操作,甚至已经有了很完善的中台系统,这里我们使用一个简单的聊天窗口,使用 node 启动服务来实现。
HTML
我们先使用htm
l 来写出来一个页面,大家先来看一下最终实现的效果是什么样子的:
这里的话,我把
node
服务端代码 和 js
代码分开了, 我把 js
直接写在了 HTML
中, 因为本身也没有多少代码,就没有外链,页面上的实现是比较简单的,就是一个表单,一个文本域,然后我们需要获取这些元素的相关 DOM
侦听对应事件,发送消息我们使用 post
请求,获取消息我们使用 get
请求
// css
<style>
textarea{
width: 1200px;
height: 600px;
resize: none;
background-color: white;
overflow: auto;
}
input{
height: 30px;
line-height: 30px;
font-size: 25px;
}
input[name=msg]{
width: 800px;
}
button{
width: 80px;
height: 30px;
}
</style>
// body
<body>
<textarea disabled></textarea>
<form action="#">
<input type="text" name="user">说:
<input type="text" name="msg">
<button type="submit">提交</button>
</form>
<script>
var form,textarea;
init();
function init(){
form=document.querySelector("form");
textarea=document.querySelector("textarea");
form.addEventListener("submit",submitHandler);
setInterval(getMsg,100);
}
function submitHandler(e){
e.preventDefault();
var fd=new FormData(form);
var data={};
for(var [key,value] of fd){
if(value.trim().length===0) return;
data[key]=value;
}
sendMsg(JSON.stringify(data));
form.children[1].value="";
}
async function getMsg(){
var data=await fetch("http://localhost:4030/");
data=await data.json();
console.log(data)
textarea.value=data.reduce((v,t)=>{
return v+t.user+":"+t.msg+"\n";
},"");
}
async function sendMsg(body){
var data=await fetch("http://localhost:4030/send",{method:"post",body});
data=await data.json();
if(!data.result){
console.log("通信失败")
}
}
</script>
</body>
node
下面是最主要的服务部分,这里我们使用http
的createServer
来启动一个服务,这里我们侦听了自己的端口号,但是如果我们在同一网络下,是可以使用另一台电脑,通过访问我们这台电脑的ip
来进行互动的, 把上面 HTML 的请求,改成我们启动了这个服务的本机的ip
就可以。
这里使用nodemon
来启动服务
const http=require("http");
const msgList=[];
const querystring=require("querystring");
http.createServer(async function(req,res){
var type=req.url.split("?")[0];
res.writeHead(200,{
"Content-Type":"text/html;charset=utf-8",
// 允许跨域访问发送数据
"Access-Control-Allow-Origin":"*",
// 允许跨域时修改请求方式
"Access-Control-Allow-Methods":"PUT",
// 允许前端发送来自定义的请求头
"Access-Control-Allow-Headers":"X-Name",
// 如果需要发送自定义响应头,需要浏览器可以获取必须使用这个来设置需要发送的自定义响应头
"Access-Control-Expose-Headers":"X-Session-Id",
"X-Session-Id":"1011101"
})
router(type,req,res)
}).listen(4030);
function getData(req){
return new Promise(function(resolve,reject){
var data="";
req.on("data",function(chunk){
data+=chunk;
// for(var i=0;i<chunk.length;i++){
// data+=String.fromCharCode(chunk[i]^2345);
// }
// for(var i=0;i<chunk.length;i+=2){
// data+=String.fromCharCode(parseInt(chunk[i+1].toString(16).padStart(2,"0")+chunk[i].toString(16).padStart(2,"0"),16))
// }
})
req.on("end",function(){
resolve(data);
})
})
}
function router(type,req,res){
switch(type){
case "/send":
return sendMsg(req,res);
case "/":
return getMsg(req,res);
}
}
async function sendMsg(req,res){
var data=await getData(req);
try{
data=JSON.parse(data);
}catch(e){};
msgList.push(data);
res.end(JSON.stringify({result:true}))
}
function getMsg(req,res){
res.end(JSON.stringify(msgList));
}