一、基础知识
1、运行:
- 创建编写js脚本文件
- 打开终端,定位到脚本所属目录
- 输入
node 文件名
执行对应文件(cls清屏,dir看目录)
注意: - 文件名不要用node.js命名
- 浏览器是不认识node代码的
- 在node中采用EcmaScript编码,没有BOM、DOM(即没有window和document),和浏览器中的JavaScript不一样。
- 浏览器中的JavaScript是没有文件操作能力的,但是node中的JavaScript具有文件操作能力。
fs是file-system的简写,就是文件系统的意思。在node中如果想要进行文件操作,就必须引入fs这个核心模块。在fs这个核心模块中就提供了文件操作相关的API,例如fs.readFile就是用来读取文件的。
注意:文件操作路径中,相对路径设计是相对于执行node命令所处路径。
//1、使用require方法加载fs核心
var fs=require('fs')
//2、读取文件,第一个参数是要读取文件的路径,第二个参数为回调函数.
//读取成功:data 数据,error null
//读取失败:data undefined,error 错误对象
//文件中存储的其实都是二进制数据,我们可以通过toString方法将其转化为我们能认识的字符
fs.readFile('./data/hello.txt',function(error,data){
if(error){console.log('读取文件失败')}
else{console.log(data.toString())}
})
//3、写文件(文件路径、文件内容、回调函数)
fs.writeFile('./data/你好.md','大家好!',function(error){console.log('文件写入成功')})
2、核心模块:
node为js提供了很多服务器级别的API,这些API绝大多数都被包装到了一个具名的核心模块中了。例如文件操作的fs模块,http服务构建的http模块,path路径操作模块(用来操作路径),os操作系统信息模块(用来获取机器信息)。均用require进行引用。可在node官网中找到各模块的方法应用。node官网doc
例子:
//用来获取机器信息
var os=require('os')
//用来操作路径的
var path=require('path')
//获取当前机器的CPU信息
console.log(os.cpus())
//memory内存
console.log(os.totalmem())
//获取一个路径中的扩展名部分
console.log(path.extname('c:/a/b/c/d/hello.txt'))
http模块
//你可以使用node构建一个web服务器
//在node中专门提供了一个核心模块:http,他的职责就是帮你创建编写服务器
//1、加载http核心模块
var http=require('http')
//2、使用http.createServer()方法创建一个Web服务器
//返回一个Server实例
var server=http.createServer()
//3、服务器的作用:提供数据
//发请求-接受请求-处理请求-发送响应
//注册request请求事件,当客户端请求过来,就会自动触发服务器的request请求事件,然后执行第二个参数:回调处理函数
//request请求事件处理函数,需要接收两个参数:
// request请求对象:请求对象可以用来获取客户端的一些请求信息,例如请求路径
// response响应对象:响应对象可以用来给客户发送响应消息
server.on('request',function(request,response){
//这里的请求路径指的是端口号后面的路径
console.log('收到客户端的请求了,请求路径是:'+request.url)
//response对象有一个方法:write,可以用来给客户端发送响应数据
//write可以使用多次,但最后一定要使用end来结束响应,否则客户端会一直等待
//response.write('hello')
//response.write('node.js')
//告诉客户端,响应结束了,可以将内容呈递给用户了
//response.end()
//response.end('hello node.js')//发送数据同时结束响应,响应内容只能是二进制或字符串
//根据不同的请求路径发送不同的响应结果
//1、获取请求路径
// request.url获取的是端口号之后的那一部分路径,也就是说所有的url都是以/开头的
//2、判断路径处理响应
//var url=request.url
// if(url==='/'){
// response.end("index page")
// }else if(url==='/login'){
// response.end("login page")
// }else{
// response.end('404 not found')
// }
var url=request.url
if(url==='/products'){
var products=[{
name:"apple",
price:1888
},
{
name:"orange",
price:2888
},
{
name:"lemon",
price:3888
}
]
//因为响应内容只能是二进制或字符串,对于数组对象可以用以下语句转化类型
response.end(JSON.stringify(products))
}
})
//4、绑定端口号,启动服务器(ctrl+C关闭服务)
server.listen(3000,function(){
console.log('服务器启动成功,可以通过http://127.0.0.1:3000/ 来进行访问')
})
path路径操作模块
//获取文件名
path.basename('c:/a/b/c/index.js')//index.js
path.basename('c:/a/b/c/index.js','.js')//index
//获取目录名
path.dirname('c:/a/b/c/index.js')//c:/a/b/c
//获取文件扩展名
path.extname('c:/a/b/c/index.html')//.html
//判断一个路径是否为绝对路径
path.isAbsolute('c:/a/b/c/index.js')//true
//前面语句功能的总结
path.parse('c:/a/b/c/index.js')
//{root:'c:/',dir:'c:/a/b/c',base:'index.js',ext:'.js',name:'index'}
//拼接路径
path.join('c:/a','b')//c:\\a\\b
Node中的其它成员
在每个模块中,除了require、exports等模块相关API之外,还有两个特殊的成员:
__dirname:可以用来动态获取获取当前文件模块所属目录的绝对路径
__filename:可以用来动态获取获取当前文件的绝对路径
__dirname和__filename是不受执行node命令所属路径影响的
console.log(__dirname)//D:\vscode
console.log(__filename)//D:\vscode\dirfilename.js
fs.readFile(path.join(__dirname,'./a.txt'),
function(err,data){})
- 在文件操作中,使用相对路径是不可靠的,因为在node文件操作路径被设计为相对于执行node命令所处的路径。为了解决这个问题,很简单,只需要把相对路径变为绝对路径。这里可以用__dirname或者__filename解决。
- 模块中的路径标识和文件操作中的相对路径标识不一致,模块中的标识就是相对于当前文件模块,不受执行node命令所处路径影响:如require(’./b’)不需要改变路径。
3、node简单的模块化
凡是第三方模块都必须用npm下载下来。
模块的加载与导出:require与exports
模块与模块之间的通信:
在node中,模块有三种:具名的核心模块,如fs;用户自己编写的文件模块;相对路径必须加./。
require方法有两个作用:1、加载文件模块并执行里面的代码2、拿到被加载文件模块导出的接口对象。
优先从缓存加载:require不会重复加载,如a加载b,a,b都加载c,则a不会重复加载c,因为b已经记载了。
每个文件模块中都提供了一个对象:exports,exports默认是一个空对象。把所有需要被外部访问的成员挂载到exports中。
名称 | 作用 |
---|---|
exports | 导出多个成员(必须在对象中) |
module.exports | 如 module.exports=''hello ,导出单个成员,拿到的就是函数、字符串,多次定义则后者覆盖前者。但可以赋值一个对象,也就相当于导出多个成员 |
//a.js
//require是一个方法
//它的作用是用来加载模块的
//在node中,模块有三种:具名的核心模块,如fs;用户自己编写的文件模块;相对路径必须加./
//在Node中,没有全局作用域,只有模块作用域:外部访问不到内部,内部也访问不到外部
//默认都是封闭的
//有时候我们加载文件不仅仅是为了简简单单执行里面的代码,更重要的是为了使用里面的成员->加载与导出
console.log('a start')
//得到的是exports对象
var bexports=require('./b.js')
console.log(bexports.foo)
console.log(bexports.age)
console.log(bexports.add(10,20))
console.log("a end")
//b.js
console.log('b start')
require('./c.js')
var age=18
console.log("b end")
exports.foo='hello'
exports.age=age
exports.add=function(x,y){
return x+y
}
//c.js
console.log('ccc')
4、一些计算机网络知识
- ip地址和端口号的概念
ip地址用来定位计算机,端口号用来定位具体的应用程序。所有需要联网通信的应用程序都会占用一个端口号。端口号的范围:0-65536。在计算机中一些默认端口号,最好不要使用,例如http服务的80。(平时访问网页时是浏览器会自动开一个端口号进行连接)
可以同时开启多个服务,但不同服务需要使用不同的端口号。 - 响应内容类型Content-type
在服务器端默认发送的数据,其实时utf-8编码的内容,但是浏览器不知道是utf8内容,浏览器在不知道服务器响应内容的编码的情况下会按照当前的操作系统的默认编码去解析,中文操作系统默认gbk,解决方法就是设置响应头告诉浏览器发送的内容是什么编码的。在http协议中,Content-Type就是用来告诉对方我给你发送的是什么数据。
response.setHeader('Content-Type','text/plain; charset=utf-8')
- 发送文件中的数据
var url=req.url
if(url==='/'){
fs.readFile('./简单的模块化/test.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==='/img')//url:统一资源定位符,一个url最终其实要对应一个资源
{
fs.readFile('./1.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)
}
})
}
5、模板引擎
模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。
6、npm命令
npm --version
自己升级自己
npm install --global npm
一次性把dependencies选项中的依赖项全部安装
npm install
只下载
npm install 包名 简写 npm i 包名
下载并保存依赖项(package.json文件(包描述文件)中的dependencies项)
npm install --save 包名 简写 npm i -S 包名
npm uninstall 包名 只删除
npm uninstall --save 包名 删除同时删除依赖包
二、express
原生的http在某些地方表现不足以应对我们的开发需求,所以我们就需要使用框架来加快我们的开发效率,框架的目的就是提高效率,让我们的代码更加高度统一。
express官网
1、安装
官网安装教程
npm init
npm install express --save
npm install express-generator -g
express --view=ejs 以管理员身份运行命令
修改完代码自动重启(即不用重新启动服务):
npm install --global nodemon
nodemon js文件名
2、基本使用
简化http操作,可以不用设置响应头。路由器:请求方法、请求路径、请求处理函数。
//0.安装
//1、引包
var express=require('express')
//2、创建服务器应用程序,也就是原来的http.createServer
var app=express()
//公开指定目录或者直接用router
//只要这样做,就可以直接通过/public/xx的方式访问public目录中的所有资源,如http://127.0.0.1:3000/public/1.jpg
app.use('/public/',express.static('./public/'))
//当省略第一个参数的时候,则可以通过省略/public方式直接访问public文件中的资源http://127.0.0.1:3000/1.jpg
app.use(express.static('./public/'))
//a相当于public的别名
app.use('/a/',express.static('./public/'))
//当服务器收到get请求的时候,执行回调处理函数
app.get('/',function(req,res){
res.send('hello express!')
})
//相当于sever.listen
app.listen(3000,function(){
console.log('app is running !')
})
- 在express中配置使用art-template模板引擎
art-template官方文档
安装:
npm install --save art-template
npm install --save express-art-template
使用:
//express-art-template依赖art-template
app.engine('html',require('express-art-template'))
app.get('/',function(req,res){
//第一个参数不能写路径,默认回去项目中的views目录中查找改模板文件,第二个参数为模板数据,可省略
res.render('test.html')
})
app.get('/admin',function(req,res){
res.render('admin/test.html',{
title:'管理系统'
})
})
//如果想要修改默认的views目录,则可以
//app.set('views',render函数的默认路径)
- 在express获取表单post请求数据
在express中没有内置获取表单请求体API,这里我们需要使用一个第三方包:body-parser.
官方文档
安装:
npm install --save body-parser
配置:
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
//配置body-parser中间件
//只要加入这个配置,则在req请求对象上多出来一个属性:body,也就是说可以直接通过req.body来获取表单post请求数据了
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.use(function (req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
})
- 在express获取表单get请求参数
express内置了一个API,可以直接通过req.query
来获取
req.params,req.query是用在get请求当中,而req.body是用在post请求中的。
表单数据传送formdata
3、mysql
官方文档
安装
npm install mysql
JSON.stringify()的作用是将 JavaScript 对象转换为 JSON 字符串,而JSON.parse()可以将JSON字符串转为一个对象。