Node.js概述
有句话说叫:“能用JS解决的事情,最后都会用JS去解决。”,JS的强大可见一斑。
node.js的官网:https://nodejs.org/en/
node.js的中文手册:http://nodejs.cn/
CNODE社区:http://cnodejs.org
使用NVM
使用NVM可以轻松的更换Nodejs的版本
。
下载地址:https://github.com/coreybutler/nvm-windows/releases/tag/1.1.7
下载可安装到随机目路。
在cmd上打出:nvm,测试有无版本号出现,若无电脑重启一次再试。
部分指令:
nvm list // 显示已安装的版本(同 nvm list installed)
nvm list installed // 显示已安装的版本
nvm list available // 显示所有可以下载的版本
nvm install 14.5.0 // 安装14.5.0版本node
nvm install latest // 安装最新版本node
nvm use 14.5.0 // 使用14.5.0版本node
nvm uninstall 14.5.0 // 卸载14.5.0版本node
nvm arch :显示node是运行在32位还是64位系统上的
nvm on // 开启nodejs版本管理
nvm off // 关闭nodejs版本管理
nvm proxy [url] // 设置下载代理。不加可选参数url,显示当前代理。将url设置为none则移除代理。
nvm node_mirror [url] :// 设置node镜像。默认是https://nodejs.org/dist/。如果不写url,则使用默认url。设置后可至安装目录settings.txt文件查看,也可直接在该文件操作。
nvm npm_mirror [url] :// 设置npm镜像。https://github.com/npm/cli/archive/。如果不写url,则使用默认url。设置后可至安装目录settings.txt文件查看,也可直接在该文件操作。
nvm root [path] // 设置存储不同版本node的目录。如果未设置,默认使用当前目录。
nvm version // 显示nvm版本。version可简化为v。
我们一般只需要用到两个指令
nvm install 14.5.0
nvm use 14.5.0
Node.js是什么?
1、Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine.
Node.js是一个构建在Google浏览器V8内核上的Javascript运行环境。(Ryan Dahl在2008年将新发布的V8内核移植了出来,从此浏览器之外也可以解析JS语句。它只有核心ECMAScript语法,因为它不需要处理网页事情)
- 代码只是具有特定格式的字符串而已,解析引擎可以去帮助解析。
2、( 特性 ) As an asynchronous event-driven JavaScript runtime、Non-Blocking
- event-driven
异步事件驱动
- Non-Blocking
非阻塞式IO模型
- lightweight and efficient 轻量和高效
3、Node.js‘package ecosystem npm
- 使用npm管理包,npm是世界上最大的开源库生态系统
- 网站:https://www.npmjs.com/get-npm
Node.js能做什么?
- Web服务器后台
- B/S编程模型Browser-Server,所有服务器后台都采用的一种模型。
- Node只是作为B/S模型,也就是打开服务器后台黑盒子的一个工具而已。
- 命令行工具
- npm ( node )
- git ( c语言 )
- hexo ( node )
安装与环境
- node.js的官网:https://nodejs.org/en/
- 从官方网址下载安装包,一路next安装到指定文件夹下。
- 打开cmd命令行,输入node -v,如有版本号,说明安装成功。
- 如要求设置环境变量,就去把文件路径添加到环境变量中。
Hello_World
自建一个xxx.js文件
var foo = 'hello world!' console.log(foo);
cmd 进入到文件目路下
>>> node xxx.js >>> hello world!
NodeJS应用示例
fs模块
var fs = require('fs') //加载模块
//第一个参数是路径,第二个参数是一个回调函数
//error:
//成功,error=null,失败,error就是错误对象;
fs.readFile('路径',function( error, data ){
if(error){
console.log('读取失败')
}else{
console.log(data) //打印二进制数据
console.log(data.toString()) //转字符串输出
}
})
var fs = require('fs') //加载模块
//第一个参数是路径,第二个文件内容,第三个参数是一个回调函数
//error:写入成功,error=null,失败error就是错误对象;
fs.writeFile('路径','内容',function( error ){
if(error){
console.log('失败!')
}else{
console.log('成功!')
}
})
http模块
域名(www.xxx.com)是用来方便记忆,而计算机会用DNS将其解析成ip地址。
IP和端口号
- IP地址用来定位计算机。
- 端口号用来定位具体的应用程序。
- 一切需要连网的软件都会占用一个端口号
- 端口号的范围从0-65536
- 有一些默认的端口号,最好不要去使用,如http服务的80。
node可以非常轻松的构建一个web服务器
var http = require('http'); //加载模块
//创建web服务器,返回一个Server实例
var server = http.createServer();
//request请求事件处理函数,需要两个参数
//Request请求对象
//Request响应对象
//服务器的工作:发请求、接收请求、处理请求、反馈请求
server.on('request',function(request,response){
console.log('收到客户端的请求了,请求路径是:'+request.url)
//告诉浏览器发送的编码格式。text/plain普通文本、text/html为html文本
//尽量填写正确的格式。
response.setHeader('Content-Type','text/plain; charset=utf-8');
//response有个方法write可以给客户端发送响应数据
//write使用完后,一定要使用end来结束。
//response.wirte('hello');
//response.end();
//也可以直接
//response.end('hello');
var url = request.url;
if(url === '/'){
response.end('index page');
}else if(url == '/login'){
response.end('login page');
}else if(url == '/pros'){
var pros = [
{
name:'apple',
price: 8888
},
{
name:'boluo',
price: 1788
},
{
name:'xiaolajiao',
price: 4500
}
]
//response.write('pros page');
response.end(JSON.stringify(pros));
}else {
response.end('404 Not Found.');
}
})
//绑定端口号,启动服务器
server.listen(3000,function(){
console.log('服务器启动成功了,可以通过http://127.0.0.1:3000/访问');
})
发送文件中的数据
index.html
<html>
<head>
</head>
<body>
<text>首页</text>
</body>
</html>
123.jpg
var http = require('http')
var fs = require('fs')
var server = http.createServer()
server.on('request',function(req,res){
var url = req.url
if(url == '/'){
fs.readFile('index.html',function(err,data){
if(err){
res.setHeader('Content-Type','text/plain;charset=utf-8')
res.end('文件读取失败,请稍后重试!')
}else{
res.setHeader('Content-Type','text/html;charset=utf-8')
res.end(data)
}
})
}else if(url == '/baby'){
fs.readFile('123.jpg',function(err,data){
if(err){
res.setHeader('Content-Type','text/plain;charset=utf-8')
res.end('文件读取失败,请稍后重试!')
}else{
res.setHeader('Content-Type','image/jpeg)
res.end(data)
}
})
}else{
res.end('404 Not Found.');
}
})
//绑定端口号,启动服务器
server.listen(3000,function(){
console.log('服务器启动成功了,可以通过http://127.0.0.1:3000/访问');
})
os模块
var os = require('os')
console.log(os.cpus()) //获取CPU信息
console.log(os.totalmem()) //获取内存
调用自己的模块
//b.js文件
var foo = 'ccc'
exports.foo = 'hello'
exports.add = function(x,y){
return x+ y
}
var age = 18
exports.age = age
模块调用的原理就是,接收文件导出的exports的全体对象。
//a.js文件
var bExports = = require('./b')
console.log(bExports.foo)
console.log(bExports.add(10,30))
console.log(bExports.age)
服务器的资源访问
( Apache )实现服务器软件,通过一个目路,所有放在目路下的资源,都可以通过地址访问!
var http = require('http')
var fs = require('fs')
var server = http.createServer()
var Dir = 'C:/app/www'
server.on('request',function(req,res){
var url = req.url
var filePath = '/index.html'
//如果url不是在根目路下,就把路径值取出来,读取这个文件
//如果在,因为filePath初始值就为主页面,先点击是他,后点击也会取路径。
if(url !== '/'){
filePath = url
}
fs.readFile( Dir + filePath ,function(err,data){
if(err){
return res.end('404')
}
res.end(data)
})
})
server.listen(3000,function(){
console.log('服务器开启')
})
如何将对应请求发送的对应html页面中的数据替换掉?
通过各种API获取到你要的数据,不管是路径数据还是其它的数据,使用”双括号”模板引擎将其数据替换
( Apache )服务器
template.html文件
<html>
<body>
...
item
...
</body>
</html>
.js文件
var http = require('http')
var fs = require('fs')
var server = http.createServer()
var Dir = 'C:/app/www'
server.on('request',function(req,res){
var url = req.url
var filePath = '/index.html'
fs.readFile('./template.html',function(err,data){
if(err){
return res.end('404')
}
fs.readdir( Dir , function(err,files){
if(err){
return res.end('404')
}
//生成要替换的内容
var content = ''
//forEach()是循环接口函数,files接收到了一个列表,而item就是列表中的每个元素,index变量就是下标
files.forEach(function(item){
//EcmaScript6在这种字符串中,可以使用${}引用变量
content += `<tr class='adr'>${item}</tr>`
})
data = data.toString()
//替换字符串,Item为html页面模板中的一个段字符串
data = data.replace('Items',content)
res.end(data)
})
})
})
server.listen(3000,function(){
console.log('服务器开启')
})
art-template模板引擎
最简单的方法就是使用npm指令安装:
npm install art-template –save
在前端使用示例
<script src="node_modules/art-template/lib/template-web.js"></script>
<script type="text/template" id="tpl">
nih{{name}}
hfjds{{age}}
</script>
<script>
//是哦那个template函数(标签id,数据)
//模板不关系内容,只关心{{}}
var ret = template('tpl',{
name:'jagf',
age: 18
})
</script>
在服务器使用示例
API文档:http://aui.github.io/art-template/
模板引擎最开始就是使用在服务器中。
- 安装
npm install art-template –save
- 加载
var template = require(‘art-template’)
- 使用API
var template = require('art-template')
var tplStr = `
<html>
<body>
...
我叫:{{name}}
年龄:{{age}}
我喜欢:{each hobbies} {{$value}} {{/each}}
...
</body>
</html>
`
var ret = template.render(tplStr,{
name:'SY',
age:18,
hobbies:[
'打球',
'唱歌',
'跳舞'
]
})
console.log(ret)
读取文件示例:
//tpl.html
<html>
<body>
...
我叫:{{name}}
年龄:{{age}}
我喜欢:{each hobbies} {{$value}} {{/each}}
...
</body>
</html>
var template = require('art-template')
var fs = readFile('./tpl.html',function(err,data){
if(err){
return console.log('读取失败')
}
var ret = template.render(data.toString(),{
name:'SY',
age:18,
hobbies:[
'打球',
'唱歌',
'跳舞'
]
})
console.log(ret)
})
同步和异步渲染
同步渲染:服务器渲染,只需要一次请求即可。增加了服务器的压力。可以被SEO搜索优化。
异步渲染:客户端渲染,需要两个以上的亲求,速度更快。不能被SEO搜索优化。
目路
/
/node_model
/public
/public/css
/public/css/main.css
/public/js
/public/js/main.js
/public/lib
/public/lib/jquery.js
/views
/views/index.html
.html
//我们约定,把所有静态资源都存放在public目路中
var http = require('http')
var fs = require('fs')
var comments = [
{
name: '张三1',
message: 'cold',
dataTime: '2021-05-31'
},
{
name: '张三2',
message: 'cold',
dataTime: '2021-05-31'
},
{
name: '张三3',
message: 'cold',
dataTime: '2021-05-31'
},
{
name: '张三4',
message: 'cold',
dataTime: '2021-05-31'
},
{
name: '张三5',
message: 'cold',
dataTime: '2021-05-31'
},
]
http
.createServer(function (req, res) {
//使用url.parse方法将路径解析为一个方便操作的对象,第二个参数true表示
//直接将查询字符串转为一个对象(通过 query 属性来访问)
var parseObj = url.parse(req.url, true)
//单独获取不包含查询字符串之后的内容(不包含?之后的内容)
var pathname = parseObj.pathname
//var url = req.url
if(pathname === '/') {
fs.readFile('./index.html',function (err, data) {
if (err) {
return res.end('404 Not Found.')
}
var htmlStr = template.render(data.toString(), {
comments: comments
})
res.end(htmlStr)
})
} else if (pathname === '/post') {
fs.readFile('./view/post.html', function (err, data) {
if (err) {
return res.end('404 Not Found.')
}
res.end(data)
})
} else if (pathname.indexOf('/public/') === 0) {
// /public/css/main.css
// /public/js/main.js
// /public/lib/jquery.js
//统一处理:
//如果请求的路径是以 /public/开头的,
//我们就可以把请求路径当作文件路径来直读取。
fs.readFile('.' + pathname, function (err, data) {
if (err) {
return res.end('404 Not Found.')
}
res.end(data)
})
} else if (pathname === '/pinglun') {
//响应客户端内容
//res.end(JSON.stringify(parseObj.query))
//我们已经使用url模块的parse方法把请求路径中的查询字符串给解析成了一个对象
//所以接下来要做:
// 1、获取表单提交的数据 parseObj.query
// 2、生成日期到数据对象中,然后存储到数组中
// 3、让用户重定向跳转到首页 /
var comment = parseObj.query
comment.dateTime = '2021-05-31 22:06:23'
comments.push(comment)
//如何通过服务器让客户端重定向
// 1、状态码设置为302临时重定向
// 2、在响应头中通过Location告诉客户端往哪重定向
// 3、客户端发现手袋服务器的响应的状态码是302就会自动去响应头中找Location,然后对该地址发起新的请求
res.statusCode = 302
res.setHeader('Location', '/')
res.end()
} else {
//其它的都处理成404找不到
fs.readFIle('./views/404.html', function (err, data) {
if (err) {
return res.end('404 Not Found.')
}
res.end(data)
})
}
})
.listen(3000, function () {
console.log('running...')
})