一、NODEJS概述
NODEJS基于谷歌的V8引擎(JS解释器),运行在服务器端的语言,基于JS。
http://nodejs.org 英文官网
http://nodejs.cn 中文
1、对比JS和NODEJS
(1)JS运行在浏览器端,存在兼容性的问题;NODEJS运行在服务器端,不存在兼容性问题。
(2)两者都有内置(ES)对象、自定义对象、宿主对象(根据执行环境的不同)
(3)JS用于网页中的交互效果,NODEJS用于服务器端操作,例如:创建web服务器、操作数据库...
2、NODEJS的执行方式
脚本模式 node C:/xampp/..../01.js
交互模式
node 回车 进入交互模式
两次ctrl+c或者输入 .exit 退出交互模式
3、 NODEJS特点及应用
支持数万个并发连接
应用于基础社交网络的大规模web应用
4.全局对象
NODEJS: global
在交互模式下,声明的变量和创建的函数都是全局对象下的,可以使用global来访问,例如 var a=1; global.a
在脚本模式下,文件中声明的变量和创建的函数不是全局对象下的,不能使用global来访问
JS: window
在浏览器下,文件中声明的变量和创建的函数是全局对象下的,可以使用window来访问,例如 var a=1; window.a
(1)console对象
global.console.log() 打印日志
global.console.info() 打印消息
global.console.warn() 打印警告
global.console.error() 打印错误
global.console.time('自定义字符串'); 开始计时
global.console.timeEnd('自定义字符串'); 结束计时
自定义字符串前后要保持一致
(2)process
当前计算机的进程
process.arch 查看当前CPU的架构 X64
process.platform 查看当前的操作系统 win32
process.env 查看当前的环境变量有哪些
process.version 查看当前nodejs的版本号
process.pid 查看当前的进行编号
process.kill(编号) 杀死某个编号的进程
(3)Buffer
缓冲区:在内存中存储数据的区域,存储网络传输时的资源。
创建buffer
var buf=Buffer.alloc(5, 'abcde');
将buffer数据转为普通字符串
buf.toString()
练习:创建两个buffer区域,分别存储两个数字,计算两个数字相加。
5.模块系统
模块是一个预定义好的功能体,在nodejs下,每一个文件都是一个模块。
在NODEJS下分为自定义模块、核心模块(官方提供)、第三方模块
在NODEJS下,一个文件就是一个模块,文件中的代码默认是被一个构造函数所包含。
以下红色的代码都是nodejs自动为每个文件添加的。
(function(exports,require,module,__filename,__dirname){ 程序编写的代码 }) |
__filename 当前文件的完整路径和文件名称 __dirname 当前文件的完整路径 require 是一个函数,用于引入模块; require('./07_2.js') module 指代当前的模块 module.exports 当前模块导出的对象(公开的内容),可以供其它的模块使用的属性和方法。 exports 等价于module.exports |
1.模块
|
以路径开头 |
不以路径开头 |
文件模块 |
require('./circle.js') 常用于用户自定义模块,如果后缀名是js是可以省略的 |
require('url') 常用于引入官方提供的核心模块 |
目录模块 |
require('./02_2') 会在当前目录下的02_2中寻找package.json文件中的main属性对应的值,如果不存在该文件,则自动寻找index.js |
require('04_2') 要求引入的目录出现在node_modules中,如果找不到,则会到上一级目录查找,直到顶层。常用于第三方模块。 |
练习:创建模块03_1.js,引入当前目录下的03_2目录模块,在03_2下创建my.js,在该文件下导出一个方法fn(两个数字相加),在03_1.js中引入后调用该方法。
练习:创建模块05_1.js引入不带路径的目录模块05_2,05_2目录中含有hello.js文件(随便打印些内容)
2.第三方模块(包)
自动下载地址 http://www.npmjs.com
需要已经安装好了npm,随着nodejs一起安装。
切换到要下载的目录
(1)cd 完整的目录 回车
change directory
(2)在要下载的目录空白区域,按住shift,单击右键->在此处打开powershell窗口
使用npm安装
npm install 包的名称
3.核心模块
是NODEJS官方提供的模块,可以直接引入,不需要创建。
(1)查询字符串模块——querystring
查询字符串:浏览器向服务器发送请求,传递数据的一种方式
协议,域名(IP),端口
http://www.codeboy.com:80/product_details.html?lid=5&name=del
parse() 将查询字符串解析为对象
stringify() 将对象转为查询字符串
练习:把百度搜索时的查询字符串解析为对象,获取关键字
ie=utf-8&f=8&rsv_bp=0&rsv_idx=1&tn=baidu&wd=电脑
(2)url模块——url
parse() 将URL解析为对象
protocol 协议
hostname 主机(域名/ip地址)
port 端口
pathname 文件在服务器上的路径
query 查询字符串
format() 将对象转换成url
query属性对应的是对象格式
练习:创建文件08_exercise.js,浏览器请求的url为
https://www.tmooc.cn:3000/course/web.html?cname=js&price=5000 服务器端获取传递的数据cname和price
4.全局函数
parseInt/parseFloat/encodeURI/decodeURI/isNaN/
isFinite/eval
(1)一次性定时器
开启定时器 var timer=setTimeout(回调函数, 间隔的时间); 当间隔时间到了,执行回调函数;单位是毫秒 清除定时器 clearTimeout(timer); |
(2)周期性定时器
开启定时器 var timer=setInterval(回调函数, 间隔的时间); 每隔一段时间,执行一次回调函数 清除定时器 clearInterval(timer) |
使用周期性定时器,每隔3秒钟打印hello,打印4次后,清除定时器。
(3)立即执行定时器(了解)
process.nextTick(回调函数) 在当前事件的结尾执行 |
var timer=setImmediate(回调函数) 清除 clearImmediate(timer) 在下一组事件的开头执行 |
5.文件系统模块——fs
用于操作服务器的文件(目录),例如:创建目录、删除目录、读取目录、创建文件、删除文件、写入文件....
(1)创建目录
fs.mkdir(路径, 回调函数)
fs.mkdirSync(路径)
(2)移除目录
fs.rmdir(路径, 回调函数)
(3)读取目录
fs.readdir(路径, 回调函数) —— 异步
fs.readdirSync(路径) —— 同步
对比同步和异步的区别
同步会阻止后续代码的执行,只有执行完以后才会执行后续代码;是通过返回值来获取结果。
异步不会阻止后续代码的执行,在整个程序的最后执行,是通过回调函数来获取结果。常用于一些比较耗时的操作。
(4)写入文件
fs.writeFile(文件路径, 数据, 回调函数)
如果文件不存在,则会创建文件,然后写入数据;如果文件已经存在,则会清空文件的内容,然后写入
(5)删除文件
fs.unlink(路径, 回调函数)/unlinkSync(路径)
(6)判断文件是否存在
fs.existsSync(路径)
(7)追加写入数据
fs.appendFile(路径,数据,回调函数)
fs.appendFileSync(路径,数据)
如果文件不存在会创建文件,如果文件已经存在,会在末尾追加写入数据。
(8)读取文件
fs.readFile(路径, 回调函数)/fs.readFile(路径)
读取的数据格式为buffer
;;判断文件num.txt是否存在,如果不存在创建文件,写入数字0。读取文件的内容,执行自增,打印出来;把自增的结果再次写入到文件中。 全部使用同步操作。
6.http协议
是浏览器和web服务器之间的通信协议
(1)通用头信息
Request URL: 请求的URL,向服务器端获取的内容
Request Method: 请求的方法 get/post get获取内容,post常用于向服务器端传递安全较高数据
Status Code: 响应的状态码
2**: 服务器成功的响应
3**: 响应的重定向,跳转到另一个URL
4**: 客户端错误
5**: 服务器错误
Remote Address: 请求的服务器的IP地址和端口号
(2)响应头信息
Connection: keep-alive; 连接的方式:持续连接
Content-Type: 响应的文件类型
Transfer-Encoding: 响应时的传输方式,chunked(分段传输)
(3)请求头信息
Accpet: 客户端接受的文件类型有哪些
Connection: 客户端和服务器端的连接方式
User-Agent: 客户端使用的浏览器
(4)请求主体
可有可无,浏览器端向服务器端传递的数据
7.http模块
可以模拟浏览器向服务器端发送请求;也可以创建web服务器
(1)模拟浏览器
http.get( url, callback ) url 请求的url callback 是回调函数,用来获取服务器端的响应 res 响应的对象 res.statusCode 响应的状态码 res.on('data', (buf)=>{ 通过事件来获取服务器端响应的数据,当有数据传递的时候,自动调用回调函数,把数据放入到buf中,格式为buffer }) |
(2)创建web服务器
var server=http.createServer() //创建web服务器 server.listen(3000) //分配端口,监听3000端口的变化 server.on('request', (req,res)=>{ }) //接收浏览器的请求,是事件的形式,一旦有请求,自动执行 req 请求的对象 url 请求的URL,用于告诉服务器要获取的内容 method 请求的方法,直接在地址栏输入默认都是get headers 请求的头信息 res 响应的对象 writeHead(状态码, { }) 设置响应的状态码和头信息;如果要跳转需要设置Location属性。 write() 将响应的数据发送到浏览器中 end() 结束响应 |
创建web服务器,监听3001端口,使用事件获取浏览器的请求,打印请求的URL和请求的方法 05_webserver.js
http://127.0.0.1:3001/admin/login.html
http://127.0.0.1:3001/member/shopping.html
创建web服务器,监听端口3000,接收浏览器端的请求
请求的URL:/login 响应文本:this is login page
请求的URL:/member 响应文本:this is member page
请求的URL:/ 跳转到:/member
如果以上都没有匹配的URL, 响应文本: 404 not found
8.express框架
基于NODEJS,用于构建web服务器的框架。
官网:www.expressjs.com.cn
安装:npm install express
const express=require('express'); //引入下载的模块 var server=express(); //创建web服务器 server.listen(3000); //监听3000端口 |
9.路由
浏览器向web服务器发送请求,web服务器会根据请求的URL和请求的方法来做出响应
res.send() 响应文本,每个路由中只能使用一次send
(1)响应对象——res
res.send() 发送文本,只能响应一次;如果是数字会认为是状态码
res.sendFile() 发送文件到浏览器,必须使用绝对路径(__dirname)
res.redirect() 响应的重定向(跳转)
创建两个路由get /home 跳转到http://www.codeboy.com
get /headpic 响应一张图片(发送文件)
(2)请求对象(req)
req.method 获取请求的方法
req.url 获取请求的url
req.headers 获取请求的头信息
req.query 获取请求时,以查询字符串传递数据,返回对象
req.params 获取路由传递的数据,返回对象
创建03_post.js,创建web服务器,新建路由(get /reg),响应一个注册文件(reg.html),文件中包含用户名、密码、邮箱、电话
10.post和get请求
get请求以查询字符串形式传递数据,服务器使用req.query获取数据,结果是对象;
post请求是通过表单提交方法传递数据,服务器端通过事件形式来获取数据(后期会有简单方法)
req.on('data', (buf)=>{ 获取的结果是buffer数据,转成普通字符串后变成了查询字符串,需要使用查询字符串模块解析为对象 }); |
11.使用路由传递数据——路由传参
设置路由中接收
server.get('/detail/:lid', (req,res)=>{ // :lid 设置数据的名称 req.params //获取路由传递的数据,格式为对象 }) |
浏览器传递数据
http://127.0.0.1:3000/detail/5
5就是传递的数据,使用lid来接收
创建购物车路由,请求的URL:/shopping,请求的方法:get,传递商品的价格(price)和商品的名称(title)
商品模块(product)
列表 /list 详情 /detail 删除 /delete
/product/list /product/detail /product/delete
用户模块(user)
列表 /list 详情 /detail 删除 /delete
/user/list /user/detail /user/delete
12.路由器
路由在使用过程中,不同的模块可能出现相同的URL,把同一个模块下的所有路由挂载到特定的前缀。
例如:商品模块下的路由挂载到product,访问形式/product/list,用户模块下的路由挂载到user,访问形式/user/list
路由器就是自定义模块(js文件),把同一个模块下的路由放到一起。
const express=require('express'); var router=express.Router(); //创建空的路由器对象 router.get('/list', (req,res)=>{ }); //往路由器中添加路由 module.exports=router; //导出路由器 |
在web服务器下使用路由器
const productRouter=require('./product.js');//引入路由器模块 server.use('/product', productRouter);//把路由器挂载到 /product下,访问形式 /product/list |
创建用户模块路由器(user.js),添加路由 用户列表(/list),用户删除(/delete),在web服务器中引入,挂载到/user下。
13.中间件(middleware)
中间件的作用为主要的业务逻辑所服务
分为应用级中间件、路由级中间件、内置中间件、第三方中间件、错误级中间件
(1)应用级中间件
每一个中间件就是调用一个函数,需要配合其他的中间件或者路由使用
server.use( 函数 ) 拦截所有的路由
server.use( '/reg', 函数 ); 拦截特定的路由
创建路由(get,/view)响应浏览器的次数,每次请求记录的次数加1。
在路由的外部初始化一个变量,值为0;在中间件中变量加1,在路由中变量发送到浏览器。
(2)内置中间件
server.use(express.static('目录'))
把静态资源文件托管到某一个目录,如果浏览器请求静态资源,则自动到这个目录下查找。
14.第三方中间件body-parser
可以将post请求的数据解析为对象
使用中间件
const bodyParser=require('body-parser'); server.use(bodyParser.urlencoded({ extended:false })); urlencoded 将post请求的数据解析为对象 extended:false 不使用第三方的qs模块,而是使用核心模块querystring将数据解析为对象 |
在路由中获取数据
req.body 返回对象格式
15.MySQL模块(同样是第三方模块)
增 INSERT INTO emp VALUES(NULL,'tom'....);
删 DELETE FROM emp WHERE eid=5;
改 UPDATE emp SET ename='tom',sex='1' WHERE eid=5;
查 SELECT * FROM emp;
mysql.exe -h127.0.0.1 -P3306 -uroot -p
(1)普通连接
var connection=mysql.createConnection({ }); 创建连接对象,传递mysql服务器的IP地址/域名,端口,用户名,密码,使用的数据库 connection.connect(); 执行连接 connection.query(sql,callback) sql要执行的SQL语句, callback回调函数,获取SQL语句结果。 connection.end(); 执行完所有的SQL语句,关闭连接。 |
(2)使用连接池
var pool=mysql.createPool({ }); 创建连接池对象,传递mysql服务器的IP地址/域名,端口,用户名,密码,使用的数据库,设置连接池的大小(connectionLimit) pool.query(sql,callback) sql执行的SQL语句,callback回调函数,获取SQL语句的执行结果。 |
用result.length作为判断是因为,result得到的是一个数组,所以可以根据数组的长度来判断
往员工表插入一条数据;修改员工编号为7的数据,生日修改为2000-1-1,工资修改为7500; 删除员工编号为10的数据;
也可以以对象的方式插入数据
修改
删除
每次运行完一组后注释。关注每个操作的结果
创建web服务器,托管静态资源到public下,在该目录下创建add.html(如下图),点击提交按钮,向服务器端发请求(get /add),服务器获取数据,把获取数据插入到tedu下的dept表中。