首先展現一下預覽效果以及文件結構:
1、預覽效果:
信息列表:javascript
編輯:css
新增:html
刪除:java
2、代碼結構:node
文件說明:1.css文件:存放項目頁面樣式
2.json:用於項目數據存儲
3.index.html:用戶列表展現頁面
4.add.html:新增|編輯用戶信息頁面
5.server.js: 啓動node服務jquery
github代碼下載地址:https://github.com/wyj2443573...git
啓動方法
:
1.進入crmNode文件,在命令控制檯中輸入node server.js 來啓動服務,出現如下提示表明成功。
2.在終端中輸入ipconfig 查看本機聯網ip:github
3.將ipv4的地址輸入到瀏覽器地址欄中,添加上端口8082,如圖所示:
到一步啓動完成。ajax
3、代碼解析json
(1)server.js 文件
主要用於1.啓動本地服務 2.寫接口文檔
用的node模塊有:http 、url、fs
接口邏輯:
- 建立服務
根據正則判斷(1.靜態資源文件請求,2.API數據接口的請求)不一樣的請求類型作不一樣的處理
- 若是是靜態資源文件請求:用fs去讀取文件,而後node服務獲取文件內容並返回客戶端。
- 若是是API數據接口請求:判斷當前操做的接口邏輯是什麼(增|刪|改|查),而後根據不一樣的邏輯去寫處理方法。整體來講無外乎fs模塊操做json文件的讀寫,http模塊將處理後的json文件中的內容返回給客戶端。
代碼(給出了相關注釋以下):
var http=require('http'), url=require('url'), fs=require('fs'); var server=http.createServer(function(req,res){ let urlObj=url.parse(req.url,true), pathname=urlObj.pathname query=urlObj.query; //query 存儲的是客戶端請求的url地址中問號傳參後面的信息 //靜態資源文件請求的處理 let reg=/\.(html|css|js|ico)/i; if(reg.test(pathname)){ let suffix=reg.exec(pathname)[1].toUpperCase(); let suffixMIME='text/html'; switch(suffix){ case "CSS": suffixMIME='text/css'; break; case "JS": suffixMIME='text/javascript'; break; } try{ let conFile=fs.readFileSync('.'+pathname,'utf-8'); res.writeHead(200,{'content-type':suffixMIME+';charset=utf-8;'}) res.end(conFile) }catch(e){ res.writeHead(404,{'content-type':'text/plain;charset=utf-8;'}) res.end('file is not found'); return; } } //API數據接口的請求 var con=null, result=null, customId=null, customPath='./json/customer.json'; //首先把customer.json中的內容都獲取到 con=fs.readFileSync(customPath,'utf-8'); con.length===0?con='[]':null;//爲了防止咱們custom.json中什麼也沒有,con也是一個空字符串,咱們會使用JSON.parse轉換的時候會報錯 con=JSON.parse(con); //1.獲取全部的客戶信息 if(pathname==='/getList'){ //開始按照API文章的規範給客戶端返回的數據 result={ code:1, msg:'沒有任何的客戶信息', data:null }; if(con.length>0){ result={ code:0, msg:'成功', data:con } } res.writeHead(200,{'content-type':'application/json;charset:utf-8'}); res.end(JSON.stringify(result)); return; } //2.獲取具體某一個客戶的信息根據客戶id if(pathname==='/getInfo'){ //把客戶端傳遞進來的ID獲取到 customId=query['id']; result={ code:1, msg:'客戶不存在', data:null }; for (var i = 0; i < con.length; i++){ if(con[i]['id']==customId){ con=con[i]; result={ code:0, msg:'成功', data:con } break; } } res.writeHead(200,{'content-type':'application/json;charset:utf-8'}); res.end(JSON.stringify(result)); return; } //3.根據id刪除用戶 if(pathname==='/removeInfo'){ customId=query["id"]; var flag=false; for (var i = 0; i < con.length; i++) { if(con[i]['id']==customId){ con.splice(i,1); flag=true; break; } } result={ code:1, msg:'刪除失敗' } if(flag){ fs.writeFileSync(customPath,JSON.stringify(con),'utf-8'); result={ code:0, msg:'刪除成功' } } res.writeHead(200,{'content-type':'application/json;charset:utf-8'}); res.end(JSON.stringify(result)); return; } //4.增長客戶信息 if(pathname==='/addInfo'){ //獲取客戶端經過請求主體傳遞進來的內容 var str=''; req.on("data",function(chunk){ //chunk實時傳輸的數據 str+=chunk; }) req.on("end",function(){ //接收數據完畢 if(str.length===0){ res.writeHead(200,{'content-type':'application/json;charset:utf-8'}); res.end(JSON.stringify({ code:1, msg:'增長失敗,沒有傳遞任何須要增長的信息' })); return; } var data=JSON.parse(str); //在現有的id中追加一個ID:獲取con中最後一項的ID,ID+1=>新ID data['id']=con.length===0?1:parseInt(con[con.length-1]['id'])+1; con.push(data); fs.writeFileSync(customPath,JSON.stringify(con),'utf-8'); res.writeHead(200,{'content-type':'application/json;charset:utf-8'}); res.end(JSON.stringify({ code:0, msg:'增長成功' })); }); return; } //5.修改客戶信息 if(pathname==='/updateInfo'){ var str=''; req.on("data",function(chunk){ str+=chunk; }); req.on("end",function(){ if(str.length===0){ res.writeHead(200,{'content-type':'application/json;charset:utf-8'}); res.end(JSON.stringify({ code:1, msg:'修改失敗,修改信息爲空' })); } var data=JSON.parse(str); var flag=false; for (var i = 0; i < con.length; i++) { if(con[i]['id']==data['id']){ con[i]=data; flag=true; break; } } if(flag){ fs.writeFileSync(customPath,JSON.stringify(con),'utf-8'); res.writeHead(200,{'content-type':'application/json;charset:utf-8'}); res.end(JSON.stringify({ code:0, msg:'修改爲功' })); } }); return; } res.writeHead(404,{'content-type':'text/plain;charset=utf-8'}); res.end(JSON.stringify({ code:1, msg:'請求接口不存在' })) }) server.listen(8082,function(){ console.log('server is success, listening on 8082 port') })
(2)index. html
主要是按照單例模式寫相關事件綁定的方法。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>node擼接口</title> <link rel="stylesheet" href="css/index.css"> </head> <body> <div class="box" > <a class="addBtn" href="add.html">增長新用戶</a> <h2 class="head"> <span>編號</span> <span>姓名</span> <span>年齡</span> <span>地址</span> <span>操做</span> </h2> <ul class="list" id="list"> </ul> </div> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script> //獲取客戶信息,完成頁面的數據綁定 var customeModule=(function(){ //Bind html var documentList=document.getElementById('list'); function bindHtml(data){ var str=''; for (var i = 0; i < data.length; i++) { var curData=data[i]; str+=`<li> <span>${curData.id}</span> <span>${curData.name}</span> <span>${curData.age}</span> <span>${curData.address}</span> <span> <a href="add.html?id=${curData.id}">修改</a> <a href="javascript:;" cusId="${curData.id}">刪除</a> </span> </li>` } documentList.innerHTML=str; } function removeCustomer(){ documentList.onclick=function(e){ var e=e||window.event, tar= e.target|| e.srcElement, tarTag=tar.tagName.toUpperCase(); //刪除操做 if(tarTag==='A'&&tar.innerHTML==='刪除'){ //確認提示框 var customId=tar.getAttribute('cusId'), flag=window.confirm('肯定要刪除編號爲['+customId+']的客戶嗎?'); if(flag){ $.ajax({ url:'/removeInfo?id='+customId, success:function(data){ if(data&&data.code==0){ documentList.removeChild(tar.parentNode.parentNode); return; } alert(data.msg); } }) } } } } //send ajax get data function init(){ $.ajax({ url:'/getList', success:function(data){ console.log(data); if(data&&data.code==0){ var data=data['data']; //綁定數據 bindHtml(data); //取消 removeCustomer(); } } }) } return{ init:init } })(); customeModule.init(); </script> </body> </html>
(3)add.html
經過URL參數判斷操做是增長客戶信息仍是編輯客戶信息。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>增長用戶</title> <link rel="stylesheet" href="css/index.css"> <style> .box2{ width:800px; margin:50px auto; font-family:Arial,"PingFang SC","Hiragino Sans GB",STHeiti,"Microsoft YaHei","WenQuanYi Micro Hei",sans-serif ; font-weight: 700; border:10px solid #dadada; text-align: center; padding:10px; } .box2 ul{ width:100%; overflow: hidden; } .box2 ul li{ width:100%; height:36px; float:left; padding:5px; text-align: center; } .box2 .type{ display: inline-block; width:60px; height:36px; line-height: 36px; } .inputInfo{ width:600px; padding:0 10px; height:36px; border:1px solid #ddd; } .submit{ display: inline-block; margin:15px auto 0; width:100px; height:36px; background-color: #179a6e; cursor: pointer; } </style> </head> <body> <div class="box2"> <ul> <li> <span class="type">姓名:</span> <input type="text" id="userName" class="inputInfo"> </li> <li> <span class="type" >年齡:</span> <input type="text" id="userAge" class="inputInfo"> </li> <li> <span class="type" >地址:</span> <input type="text" class="inputInfo" id="userAddress"> </li> </ul> <button class="submit" id="submit">提交</button> </div> </body> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script> // 獲取URL地址欄的參數值 String.prototype.queryUrlParameter=function(){ var obj={}; var reg=/([^?=&#]+)=([^?=&#]+)/g; this.replace(reg,function(){ var key=arguments[1]; var value=arguments[2]; obj[key]=value; }) return obj; } var userName=document.getElementById('userName'); var userAge=document.getElementById('userAge'); var userAddress=document.getElementById('userAddress'); var submit=document.getElementById('submit'); //判斷修改仍是增長:若是url後面傳遞了ID值就是修改,不然就是增長 var urlBoj= window.location.href.queryUrlParameter(), customId=urlBoj['id'], isFlag=typeof customId==='undefined'?false:true; //true->修改 false->增長 //若是是修改,首先須要把對應客戶的信息獲取到,而且增長到對應的文本框中。 if(isFlag){ $.ajax({ url:'/getInfo?id='+customId, success:function(data){ if(data&&data.code==0){ var result=data['data']; userName.value=result['name']; userAge.value=result['age']; userAddress.value=result['address']; } } }) } //點擊提交按鈕1.增長2.修改 submit.onclick=function(){ var obj={ name:userName.value, age:userAge.value, address:userAddress.value }; //update send ajax if(isFlag){ console.log('進入修改'); obj.id=customId; $.ajax({ url:'/updateInfo', type:'POST', data:JSON.stringify(obj), success:function(data){ if(data&&data.code==0){ window.location.href='index.html' return; } alert(data.msg); } }) return; } //add send ajax $.ajax({ url:'/addInfo', type:'POST', data:JSON.stringify(obj), //請求主體的內容是json格式的字符串 success:function(data){ if(data&&data.code==0){ //成功後跳轉回首頁 window.location.href='index.html' } alert(data.msg); } }); } </script> </html>
(4)customer.json
[{"name":"Tom","age":"20","address":"北京天通苑","id":"1"},{"name":"Tony","age":"23","address":"北京沙河","id":"2"}]
(5)index.css
*{ margin:0; padding:0; } li{ list-style: none; } .box{ width:800px; margin:50px auto; font-family:Arial,"PingFang SC","Hiragino Sans GB",STHeiti,"Microsoft YaHei","WenQuanYi Micro Hei",sans-serif ; font-weight: 700; border:10px solid #dadada; } .addBtn{ color:#179a6e; font-size:18px; } .head{ width:100%; height:30px; font-size:16px; line-height:30px; background-color: #179a6e; overflow: hidden; } .head span{ display: inline-block; float:left; width:20%; text-align: center; color:#fff; position: relative; } .head span:after{ content:''; position:absolute; width:1px; height:30px; background-color: #fff; right:0; top:0; } .list{ width:100%; } .list li{ width:100%; height:36px; line-height: 36px; overflow: hidden; border-bottom:1px solid #ddd; cursor: pointer; } .list li:hover{ background-color: #fafafa; } .list li span{ display: inline-block; width:20%; float:left; text-align: center; overflow: hidden; text-overflow: ellipsis; white-space:nowrap; }