标准js风格:
https://standardjs.com/readme-zhcn.html
2. 在文件中右键运行
3. 输入 node app或者node app.js运行
附:vscode如何实现代码提示:
-专业IT技术社区-登录 cnpm install --save @types/node4.如何在控制台中调试node 的API
任意目录下输入node,进入node环境就可以进行API测试了
5.解决修改服务程序后需要重启服务器来执行的问题
这里我们需要使用一个第三方命令行工具 nodemon
nodemon 是一个基于node开发的第三方命令行工具,
安装:
npm install --global nodemon安装完毕之后使用:只需要将启动服务命令 node app改为:
nodemon app1.没有DOM和BOM
2.控制台输出 console.log()
输出项目文件夹地址 console.log(__dirname);
输出项目文件地址 console.log(__filename);
3.定时执行
setTimeout(() => { console.log("time's up") }, 3000);4.定时循环执行
var time=0; timer1 = setInterval(() => { time += 2 console.log(time + " s passed!") if (time > 5) clearInterval(timer1); }, 2000);5. 核心模块
node专门为JS提供了很多服务器级别的API.这些API绝大多数都被包装到了一个具名的核心模块中.如 文件操作的fs核心模块,http服务构建的http模块,path路径操作模块,os操作系统信息模块.
引用方法
var 模块别名 =require('模块名')6. 自定义模块
直接require(./模块名) // 其中./表示相对路径同路径
7.作用域
在node中没有全局作用域,只有模块作用域.模块之间互不影响.
8.导出 //模块之间通讯
每个文件中都提供了一个对象叫:exports
当文件被require时,不仅会执行模块,还会接受文件的导出
1.读文件
读写文件我们要引用fs核心模块
fs.readFile(path: string | number | Buffer | URL, callback: (err: NodeJS.ErrnoException, data: Buffer) =>void): void (+3overloads)
namespacereadFile
var fs=require('fs') var rev=fs.readFile("./xiaojiejie.txt",function(err,data){ console.log(data.toString()); });
2.写文件
fs.writeFile(path: string | number | Buffer | URL, data: any, callback: NoParamCallback): void (+1overload)
namespacewriteFile
var fs = require('fs') fs.writeFile("./xiaojiejie.txt", '5.芙蓉姐姐', (err) => { if (!err) console.log("写入成功!"); }); fs.readFile("./xiaojiejie.txt", function (err, data) { console.log(data.toString()); });
3.读取目录
fs.readdir('地址',(err,strs)=>{}) //strs是一个字符串列表
fs.readdir(wwwDir, (err, strs) => { if (err) return console.log(err); for (let index = 0; index < strs.length; index++) { console.log(strs[index]); }; });http服务我们要引用http核心模块
function createServer(requestListener?: RequestListener): Server (+1overload)
http.createServer()
server.on("request",function(request,responce){}//responce响应内容只能是二进制文件或字符串
server.listen(3000,function(){}) //80端口号是浏览器默认访问的
//引用http核心模块 var http = require('http'); //实例化一个server实例 var server = http.createServer(); server.on("request", function (request,responce) { console.log("收到客户端的请求了,请求路径是:"+request.url);//服务器收到的请求 //responce.write("hello");//服务器返回给客户端的回应 //responce.end(); //回应必须告知客户端结束 responce.end("hello"); //上面两句的简写 }) //监听端口号,启动服务 server.listen(3000, () => { console.log("服务器启动成功"); });附:JSON列表字符串化
var products = [ { product: "iphone", price: "8888" }, { product: "ipad", price: "3000" }, { product: "macbook", price: "11000" } ] str=JSON.stringify(products);3.通过responce让客户端重定向
(1). responce将状态码设置为302(临时重定向)
(2). 客户端收到302后会去响应头中的Location处寻找重定向页面,并发起新的请求.
(3). 记得结束响应
rsp.statusCode=302 rsp.setHeader('Location','/') rsp.end()对于调用文件:使用require调用模块,同时还会接收模块中暴露的内容
对于被调用文件:使用exports来暴露想传递的参数或方法
例如:a.js
var b=require('./b') console.log(b); console.log(b.add(10,30));b.js
var foo="bbb"; function add(x,y){return x+y;} exports.add=add; exports.foo=foo;
1.每个通讯的软件都需要一个端口号,取值范围0~65535,
2.端口号有些被默认使用了,应该注意不要用80等已占用的
3.可以开启多个服务,但一定要确保不同服务占用的端口号不一致才可以
4.服务器默认发送数据是utf8编码的内容,但浏览器在不指定编码格式情况下会按照操作系统去解析,中文系统中是'gbk' ,应手动设置为utf-8
rsp.setHeader('Content-Type','text/plain;charset=utf-8')text/plain 是普通文本,如果返回的是html元素则 text/html 详见下一节
//引用http核心模块 var http = require('http'); //实例化一个server实例 var server = http.createServer(); server.on("request", function (request, responce) { console.log("收到客户端的请求了,请求路径是:" + request.url);//服务器收到的请求 console.log("客户端的端口号是:"+request.socket.remotePort); console.log("客户端的IP是:"+request.socket.remoteAddress); }) //监听端口号,启动服务 server.listen(3000, () => { console.log("服务器启动成功"); });
1.发送文件中的数据
发送文件中的数据要结合fs模块使用,
2.Content-Type文件格式
不同的资源对应的Content-Type是不一样的
rsp.setHeader('Content-Type','text/plain;charset=utf-8')
text/plain部分其实是在声明返回的字符串其实是什么资源,具体怎么用参照下面的网页:
HTTP Content-type 对照表 var http = require('http'); var fs = require('fs'); var sever = http.createServer(); sever.on("request", (req, rsp) => { console.log(req.url); if (req.url =="/") { fs.readFile("./res/index.html",(err,data)=>{ if (err) { console.log(err); rsp.setHeader('Content-Type', 'text/plain;charset=utf-8'); rsp.end("访问出错,原因:"+err); }else{ rsp.setHeader('Content-Type', 'text/html;charset=utf-8'); rsp.end(data); } }) }; if (req.url =="/image") { fs.readFile("./res/8.jpg",(err,data)=>{ if (err) { console.log(err); rsp.setHeader('Content-Type', 'text/plain;charset=utf-8'); rsp.end("访问出错,原因:"+err); }else{ rsp.setHeader('Content-Type', 'image/jpeg');//图片就不需要指定编码了! rsp.end(data); } }) }; if (req.url =="/txt") { fs.readFile("./res/xiaojiejie.txt",(err,data)=>{ if (err) { console.log(err); rsp.setHeader('Content-Type', 'text/plain;charset=utf-8'); rsp.end("访问出错,原因:"+err); }else{ rsp.setHeader('Content-Type', 'text/plain;charset=utf-8'); rsp.end(data); } }) }; } ); sever.listen(3000, () => { console.log("the server is good to request!"); })apache服务器软件中默认有一个www文件夹,里面的资源均可通过url来访问
var http = require('http') var fs = require('fs') var wwwDir = "./www" var server = http.createServer(); server.on('request', (req, rsp) => { console.log(req.url); var filePath='/index.html' if(req.url !=='/') filePath=req.url fs.readFile(wwwDir + filePath, (err, data) => { if (err) return rsp.end("failed to read the file"); rsp.end(data); }) }) server.listen(3000, () => { console.log("on"); })1.安装
安装:在项目文件夹执行:
npm install art-template --save
2.引包
var template=require('art-template')3.模板标记语法
模板引擎不关心内容,只关系它能认识的模板标记语法,例如{{}}
(1).template.render(str,{键值对}) //返回新的str
例子:index2.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>欢迎新同学!</h1> <h2>姓名:{{name}}</h2> <h2>年龄:{{age}}</h2> <h2>性别:{{sex}}</h2> <h3>爱好:</h3> {{each hobbies}} <p>{{$value}}</p> {{/each}} </body> </html>app.js
var http = require('http') var fs = require('fs') var template = require('art-template') var wwwDir = "./views" var server = http.createServer(); function addHtml(str, stuName, stuAge, stuSex, stuHobbies) { nstr = template.render( str, { name: stuName, age: stuAge, sex: stuSex, hobbies: stuHobbies } ); return nstr; } server.on('request', (req, rsp) => { console.log(req.url); var filePath = '/index2.html' if (req.url !== '/') filePath = req.url if (filePath = '/index2.html') { stuhtml = addHtml("lili", "18", "girl"); fs.readFile(wwwDir + '/index2.html', (err, data) => { if (err) return err; str = data.toString()// str = addHtml(str, 'lili', '18', 'girl', ['吃饭', '睡觉', '拯救世界']); console.log(str); fs.writeFile(wwwDir + '/index2.html', str, () => { fs.readFile(wwwDir + filePath, (err, data) => { if (err) return rsp.end("failed to read the file"); rsp.end(data); }) }); }) } }) server.listen(3000, () => { console.log("on"); })
4.如何在html中做标记:
template.render( str, { name:"lili", hobby:[ 'football', 'basketball', 'sing' ] })注意有一个属性是一个列表,而遍历这个列表要用
{{each 属性名}} {{遍历属性值}} //有多少个元素遍历多少次 {{/each}}<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>{{name}}</h1> {{each hobby}} <p>I love {{$value}}</p> {{/each}} </body> </html>
再来一个if else 的渲染方法
{{if 条件}} {{else}} {{/if}}
综合练习中有更多用法.
附:前端也可以用art-template进行渲染,举例如下:
我们用Ajax从服务端接收到一个数据,然后用script渲染页面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="../node_modules/jquery/dist/jquery.js"></script> </head> <body> <ul id="container"> </ul> <script id='tpl' type='text/template'> {{each todos}} <li> {{ $value.title }}</li> {{/each}} </script> <script src="../node_modules/art-template/lib/template-web.js"></script> <script> $.get( 'http://127.0.0.1:3000/todos', (data) => { var htmlStr=template('tpl',{ todos:data }) $('$container').html(htmlStr) }) </script> </body> </html>1.引用模块
var http = require('http')2.url解析URL
url.parse('http://127.0.0.1:3000/comment?name=啊&msg=啊啊')
其中:
search:查询字符串, query:不含?的查询字符串
pathname:不包含查询字符串的路径
进一步解析:
url.parse('http://127.0.0.1:3000/comment?name=啊&msg=啊啊',true)
query解析成对象了
1.npm安装模块
npm install silly-datetime
2.在JS中的应用
var sd = require('silly-datetime'); var time=sd.format(new Date(), 'YYYY-MM-DD HH:mm:ss'); console.log(time);3.具体用法
var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); //获取完整的年份(4位,1970-????) myDate.getMonth(); //获取当前月份(0-11,0代表1月) myDate.getDate(); //获取当前日(1-31) myDate.getDay(); //获取当前星期X(0-6,0代表星期天) myDate.getTime(); //获取当前时间(从1970.1.1开始的毫秒数) myDate.getHours(); //获取当前小时数(0-23) myDate.getMinutes(); //获取当前分钟数(0-59) myDate.getSeconds(); //获取当前秒数(0-59) myDate.getMilliseconds(); //获取当前毫秒数(0-999) myDate.toLocaleDateString(); //获取当前日期 var mytime=myDate.toLocaleTimeString(); //获取当前时间 myDate.toLocaleString( ); //获取日期与时间
1.目录结构
2.index.html (使用了模板引擎)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>留言板</title> <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <!-- 最新的 Bootstrap 核心 JavaScript 文件 --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <style type="text/css"> * { margin: 0; padding: 0; font-family: arial, "微软雅黑"; } header { margin-top: 30px; } body { margin-left: 80px; margin-right: 80px; } a { margin-top: 10px; margin-bottom: 10px; background-color: #4CAF50; /* Green */ border: none; color: white; padding: 6px 10px; text-align: center; text-decoration: none; display: inline-block; font-size: 10px; border-radius: 5px; } ul { padding-top: 10px; border-top: 1px solid #eee; } li { border: solid; border-bottom: none; border-width: 1px; border-color: #eee; list-style: none; padding: 10px; } li:last-of-type { border-bottom: 1px solid #eee; } #title { font-size: 30px; } #subtitle { font-size: 16px; color: #999; margin-left: 10px; } </style> </head> <body> <header> <b id="title">留言板</b> <b id="subtitle">留言板</b> </header> <a href="/post">发表留言</a> <body> <div> <ul> {{each comments}} <li> {{$value.name}}说: {{$value.msg}} <span class="pull-right">{{$value.dateTime}}</span> </li> {{/each}} </ul> </div> </body> <footer> </footer> </body> </html>3.post.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>提交留言</title> <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <!-- 最新的 Bootstrap 核心 JavaScript 文件 --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <style> * { margin: 0; padding: 0; font-family: arial, "微软雅黑"; } header { margin-top: 30px; } body { margin-left: 100px; margin-right: 100px; } .clearfix:after { content: ""; display: block; clear: both; } #title { font-size: 30px; color: rgb(38, 151, 196); } #subtitle { font-size: 16px; color: #999; margin-left: 10px; } </style> </head> <body> <header> <b id="title">留言板</b> <b id="subtitle">留言板</b> <hr> </header> <body> <form action="/comment"> <div class="form-group"> <label for="name">你的大名</label><br> <input name="name" type="text" id="name" class="from-control" placeholder="请输入您的名字"> </div> <div class="form-group"> <label for="name">你的留言</label><br> <textarea name="msg" id="" cols="30" rows="10" ></textarea> </div> <button type="submit" class="btn btn-default">留言</button> </form> </body> <footer> </footer> </body> </html>4.最关键的app.js服务脚本
var http = require('http') //http核心组件 实例化服务 var fs = require('fs') //fs核心组件 文件操作 var template = require('art-template') //art-template模板引擎组件,需npm安装 var url = require('url') //url核心组件 url解析 var sd = require('silly-datetime');//silly-datetime时间组件,需npm安装 var wwwDir = "./views" //html放在此文件夹中 var comments = [] //由于没有数据库,建立一个数组来保持评论信息 var server = http.createServer();//实例化一个服务 server.on('request', (req, rsp) => { //接受请求处理函数 var obj = url.parse(req.url, true) //将请求的url转为一个对象 if (obj.pathname === '/') { //默认返回index页面 fs.readFile( //读取对应的html模板文件 wwwDir + '/index.html', (err, data) => { if (err) return rsp.end(err);//如果读取失败就报错 var revStr = template.render(data.toString(), { comments: comments }) // template.render渲染模板文件套入数据,data.toString()是fs读取的html数据 rsp.end(revStr);//将处理好的数据(字符串)响应给客户端 } ); } else if (obj.pathname === '/post') {//处理post页面 fs.readFile( wwwDir + '/post.html', (err, data) => { if (err) return err; rsp.end(data); } ) } else if (obj.pathname === '/comment') { //如果是comment,则证明此为客户端提交数据 comments.unshift({ //将客户端提交的数据写在comments中 name: obj.query.name, msg: obj.query.msg, dateTime: sd.format(new Date(), 'YYYY-MM-DD HH:mm:ss')//处理时间 }) rsp.statusCode=302 //给客户端一个302状态码,让它重定向 rsp.setHeader('Location','/') //设定重定向地址 rsp.end() //别忘了结束响应 } else { rsp.end('404 not found') //这个else是访问不存在页面的处理, } }) //开启监听3000窗口 server.listen(3000, () => { console.log("listening....."); })