Node.js入门基础总结及简单示例


前言

Node.js是基于谷歌的V8引擎,是一种运行在服务器端的JS解释器,可以实现所有后端语言的功能,例如java,php等能做的Node.js也可以。
www.nodejs.org 官网
www.nodejs.cn 中文镜像
对比JS和Node.js
JS运行在客户端浏览器,存在多款浏览器有兼容性问题;Node.js运行在
服务器端,只能谷歌V8引擎一种解释器,不存在兼容性问题;
两者都有ES(内置)对象,自定义对象;不同的宿主对象。
JS用于开发浏览器端交互效果,Node.js用于服务器的操作,例如数据库访问,网络操作等…
Node.js适合做IO操作为主应用,不适合做CPU密集型的应用。
特点
Node.js属于单线程运行逻辑,默认只使用其中一个CPU内核
支持数万个并发连接,适合开发大规模的WEB应用
运行方式
脚本模式
node 拖拽文件 回车
交互模式
node 回车 进入交互模式
两次ctrl+c 退出交互模式


在说Node.js之前,咱们先来了解一下Node.js的基本操作

Node.js对比JS

JS运行在客户端路蓝旗,存在多款浏览器,有兼容性问题;Node.js运行在服务器端,只有一种解释器,没有兼容性问题。

两者有共同的内置对象、自定义对象;以及各自宿主对象。

JS用于开发浏览器端的交互效果;Nodejs用于服务器端的开发,例如数据库访问、WEB服务器的创建…

网址

官网:www.nodejs.rog

中文翻译:www.nodejs.cn

node -v 查看版本号

特点

Node.js属于单线程运行逻辑,默认只使用其中一个CPU内核

支持数万个并发连接,适合开发大规模的WEB应用

运行方式

脚本模式

node 拖拽文件 回车

交互模式

node 回车 进入交互模式

两次ctrl+c 退出交互模式

一.Node.js概述

1.全局对象

(1) global

用于查看一个变量和函数是否为全局变量或者全局函数

   global.变量         global.函数名称()

在node.js脚本文件中不是在全局作用域下,里边的变量和函数都是局部的,可以有效防止全局污染。

在JS脚本文件中是在全局作用域下,全局对象叫 window,里边的变量和函数都是全局的,会存在全局污染。
例:编写脚本文件03_global.js,声明变量,创建函数;查看里边的变量和函数是否为全局的。

var a=1;
function func(){
    return 3;
}
//nodejs下脚本文件不是全局作用域
//a和func都是局部的,不能使用global访问
console.log( global.func() );   //运行结果:不是全局的

(2) console 对象

console.log( )    打印日志

console.info()     打印消息

console.warn()    打印警告

console.error(    打印错误

console.time(     开始计时

console.timeEnd()  结束计时

(3)process 对象

进程:计算机上每一个软件启动后都是有一个进程。

process.arch   查看当前CPU的架构

process.platform      查看当前的操作系统

process.version     查看当前node.js的版本号

process.pid     查看当前进程的编号

process.kill(进程编号)   结束制定编号的进程

(4)Buffer 对象

Buffer:缓冲区、缓冲器,内存中存储数据的区域,常用于存储网络传输的资源。

let buf=Buffer.alloc(5,'abcde');  //创建buffer空间并存储数据,每个英文字符占1个字节,汉字占3个字节
buf.toString()//将buffer转为字符串
String(buf)//将buffer转为字符串

二.模块

Node.js下,每个模块是一个功能体。

分为自定义模块核心模块第三方模块

每一个文件就是一个模块
module:当前模块的对象
require:是一个函数,用于导入另一个模块
module.exports:导出的对象,默认是一个空对象,如果要导出内容,需要放入到该对象。
__dirname:directory 当前模块的绝对路径
__filename:当前模块的绝对路径+模块名称

1.模块分类

以路经开头不以路径开头
文件模块require(’./circle.js’)
常用于引入自定义以内
require(‘querystring’)
用于引用官方提供的核心模块
目录模块require(’./02_dong’)
首先会到目录下寻找package.json文件中main对应的文件;
如果没有会自动赵找index.js
equire(‘ran’)
首先会到当前目录下的node_modules目录中寻找ran目录;
如果找不到会一直往上一级的node_modules中寻找ran目录;常用于第三方模块**

json文件:属于一种数据文件,通常放数组和对象,对象的属性名必须用双引号,字符串必须用双引号。

2.包和npm

:package,就是目录模块,也是第三方模块的叫法

npm:用于管理包的工具,包含有下载安装、升级、卸载、上传…

npm会在node.js安装时附带安装

npm -v 查看npm版本号

(1) 切换命令行的路径

cd 粘贴路径 回车

如果涉及到盘符的变化,需要添加 盘符名称: 回车

在指定的目录下的空白区域按住shift鼠标右击选择’在此处打开 powershell窗口’

(2)下载

网址www.npmjs.com

npm installl 包名称 回车

将包自动放到node_modules目录中,这个 目录不存在自动创建。,可能会下载一些其他依赖的包。同时还会产生一个package-lock.json的文件,用于记录包的版本号。

3.查询字符串(querystring)

查询字符串:浏览器向web服务器发送请求,传递数据的一种方式,位于URL中问号后的部分。

keyword=123&enc=utf-8

查询字符串模块用于操作查询字符串的工具模块。

parse() 将查询字符串解析为对象
例:获取以下查询字符串中商品的名称和价格:pname=apple&price=5199

const querystring=require('querystring');
var str='pname=apple&price=5199';
let obj=querystring.parse(str);
console.log(obj.pname);
console.log(obj.price);

在这里插入图片描述

4.URL模块

URL:统一资源定位,网络上的任何资源都有对应的URL

http:// www.codeboy.com: 9999/ prodects.html? kw=dell

协议 域名/IP地址 端口 文件在服务器上的路径 查询字符串

URL模块用于操作 URL
parse() 将一个URL解析为对象,可以得到URL中的各个部分。

5.定时器模块(timer)

(1)一次性定时器

//开启
let timer=setTimeout(回调函数,间隔时间);
//当间隔时间到了,会调用一次回调函数,单位是毫秒
//清除
clearTimeout(timer);

(2)周期性定时器

//开启
let timer=setInterval(回调函数,间隔时间);
//每个一段时间,调用一次糊掉函数
//清除
clearInterval(timer);

例:两秒打印一次,打印3次后,清除定时器

let i=0;
let timer=setInterval(()=>{
    console.log('boom');
    i++;
    if(i===3){
        clearInterval(timer);
    }
},2000);

(3)立即执行定时器

//第一种
//开启
let timer=setImmediate(回调函数);
//清除
clearImmediate(timer)

//第二种
process.nextTick(回调函数)

6.文件系统模块( fs )

文件包括文件形式和目录形式

(1)创建目录

fs.mkdirSync(目录的路径)

(2)移除目录

fs.rmdirSync(目录的路径)

(3)查看文件的状态

statSync(文件的路径)/stat(文件的路径,回调函数)
   回调函数:异步操作通过回调函数获取结果
 	err:可能产生的错误
 	s:具体的文件状态
 s.isFile()   是否为文件
 s.isDirectory    是否为目录

(4)读取文件目录

readdir(文件路径,回调函数) 获取的结果为数组形式

//异步
fs.readdir('../day02',(err,arr)=>{
    if(err) throw err;
    //读取的目录文件
    console.log(arr);
});
console.log('运行结束');

在这里插入图片描述
readdirSync(文件路径) 获取的结果为数组形式

let s=fs.readdirSync('../day02');
console.log(s);
console.log('运行结束');

在这里插入图片描述

(5)写入文件

wirteFileSync(文件的路径,写入的数据)

wirteFile(文件的路径,写入的数据,回调函数)

fs.writeFile('./1.txt','range',(err)=>{
    if(err) throw err;
    console.log('写入成功');
})

如果文件不存在,则会创建文件后写入文件
如果文件已经存在,则会原来基础上覆盖写入

(6)追加写入

appendFileSync(文件的路径,写入的数据) / appendFile(文件的路径,写入的数据,回调函数)

如果文件不存在,则会创建文件然后写入数据

如果文件已经存在,则会在文件的末尾追加写入数据
:使用异步的方法往文件3.txt中追加写入数据 Hello你好

fs.appendFile('./3.txt','Hello你好',(err)=>{
    if(err) throw err;
})

(7)读取文件

readFileSync(文件的路径) / readFile(文件的路径,回调函数)

读取的结果为buffer数据

//异步,读取stu.txt
fs.readFile('./stu.txt',(err,data)=>{
    if(err) throw err;
    console.log( String(data) );
});
//同步,读取3.txt
let s=fs.readFileSync('./3.txt');
console.log( String(s) );

(8)删除文件

unlinkSync(文件的路径) / unlink(文件的路径,回调函数)
:使用异步方法删除1.txt

fs.unlink('./1.txt',(err)=>{
    if(err) throw err;
})

(9)检测文件是否存在

existsSync(文件的路径) true —> 存在 false—> 不存在

注:只能用同步 不能用异步
:如果文件2.txt存在,则同步删除该文件;如果目录mydir2不存在,则同步创建该目录

if( fs.existsSync('./2.txt') ){
    fs.unlinkSync('./2.txt');
}
if(!fs.existsSync('./mydir2')){
    fs.mkdirSync('./mydir2')
}

(10)拷贝文件

copeFileSync(源文件,目标文件) / copeFile(源文件,目标文件,回调函数)
:拷贝文件3.txt到mydir下

fs.copyFile('./3.txt','./mydir/3.txt',(err)=>{
    if(err) throw err;
    console.log('拷贝成功');
})

:同步拷贝stu.txt到mydir下

let s=fs.copyFileSync('./stu.txt','./mydir2/stu.txt');
console.log('拷贝成功');

(11)文件流和事件

createRreadStream(文件的路径) 创建可读取的流对象
createWriteStream(文件的路径) 创建可写入的流对象
事件格式
on('事件名称',回调函数)
事件名称是固定用法,一旦触发事件自动执行回调函数
PSpipe( ) 管道,可以将读取的流添加到写入流

7.同步和异步

(1).同步:在执行的过程中按照顺序执行,会阻止后续代码的执行,如果获取结果通过返回值

//同步:从上往下执行
let s=fs.statSync('../day02');
console.log(s);
//查看是否为文件
console.log(s.isFile());
//查看是否为目录
console.log(s.isDirectory());

同步打印的返回值会根据上述代码的书写顺序一致

(2).异步:在执行的过程中如果有异步操作,会在一个独立的线程执行,不会阻止主程序中后续代码的执行;通过回调函数获取结果

let s=fs.stat('./01_homework.js',(err,s)=>{
    //err,可能产生的错误
    if(err){
        throw err;
    }
    //s获取的文件的状态
    console.log(s);
 });
console.log('运行结束');

异步打印的返回值顺序会根据代码里各自逻辑的执行速度而定,哪个先执行完哪个先打印
下图是本次异步打印的结果,最下面的外层打印比上面的函数先执行完,所以外层先打印结果
在这里插入图片描述

8.http协议

浏览器和web服务器之间的通信协议

(1)通用的头信息

Request URL:请求的URL,像服务器端请求的内容

Request Method:请求的方法,get / post

Status Code:响应的状态码

​1xx 系列:正在响应,还没有结束
​2xx 系列:成功的响应
​3xx 系列:响应的重定向,跳转到另一个URL
​4xx 系列:客户端请求错误
​5xx 系列:服务器端错误

(2)响应的头信息(Response)

Content-Type:相应的内容类型,html文件对应 text/html

Content-Length: 响应的文件长度,单位是字节

Location:要跳转的URL,需要结合着状态码3**使用

(3)请求的头信息(Request)

浏览器发出的叫做请求

(4)请求主体

传递的数据,例如注册、登陆传递数据
可有可无,没有传递数据,这项不显示。

9.http模块

可以创建web服务器,接收浏览器的请求并作出相应

const app=http.createServer(); //创建web服务器
app.listen(8080);  //设置端口,用于访问web服务器
//添加事件,通过事件来接收请求并做出响应
app.on('request',(req,res)=>{
    //req  //请求的对象
    //req.url   //获取请求的url,对应端口号后的部分
    //req.method   //获取请求的方法
    //res  //响应的对象
    res.write()    //设置响应的内容
    res.writeHead()   //设置响应的状态码和头信息,第二个参数头信息可以为空
    res.end()  //结束并发送响应
})

三.express 框架

一整套的解决方案,把用得到的功能都做到了并简化。express

基于Node.js平台,快速、开放、极简的WEB开发框架

网址:www.expressjs.com.cn

下载:npm install express

(1) 创建WEB服务器

//引入第三方模块
const express=require('express');
//创建web服务器
const app=express();
//设置端口
app.listen(8080);

(2) 路由

浏览器向web服务器发送请求,web服务器端根据请求的方法和请求的URL做出响应,用来处理特定的请求。

路由的组成请求的方法请求的URL回调函数(用来响应)

响应对象

send() 设置响应的内容并发送

redirect() 设置响应的重定向,跳转到另一个URL

sendFile() 设置响应的文件,需要绝对路径 __dirname

:根据表单提交的请求来创建对应的路由(post/mylogin),响应’登陆成功’
前端代码:

<!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>
    <h2>用户登陆</h2>
    <!-- form 用于表单提交,相当于向服务器发送请求
        method   设置请求的方法
        action   设置请求的URL
        name     保存输入的值
    -->
    <form method="POST" action="/mylogin">
        用户:<input type="text" name="uname"><br>
        密码:<input type="text" name="upwd"><br>
        <input type="submit" >
    </form>
</body>
</html>

Node.js代码:

app.post('/mylogin',(req,res)=>{
    //获取post请求的方法
    //以流的方式传递,通过添加事件获取
    //一旦数据流入,自动触发事件,通过回调函数获取数据
    req.on('data',(chunk)=>{
        console.log(chunk);//Buffer格式
        let str=String(chunk);
        console.log(str);
        //查询字符串,解析为对象
        let obj=querystring.parse(str);
        console.log(obj);
    })
    res.send('登陆成功');
});
传递方式类型在路由中获取
post传递不可见req.on(‘data’,(chunk)=>{
chunk 就是获取的数据,格式为buffer,需要转字符串,
转字符串后为查询字符串,需要解析为对象
})
查询字符串传递在URL中可见
kw=dell&price=4000
req.query 格式为对象
路由传参在URL中可见
/package/mysql
需要在路由的URL中指定形参
app.get(’/package/:pname’,(req,res)=>{
req.params //获取路由传参的数据,格式为对象
})

对比post和get的区别

post传递的数据不可见,get可见

 post可以传递大文件,get方式只能通过url中传递字符串,长度不超过4k

post传递的速度相对get慢

通常登陆、注册使用post请求,搜索使用get请求

四.路由器

用来管理路由,将同一个模块下的路由归纳到一起;可以有效的进行分工协作,还可以防止URL冲突。

路由器

const express=require('express');
//创建路由器对象
const r=express.Router();
//往路由器下添加路由
r.get('/list',(req,res)=>{
res.send('这是用户列表');
});
//导出路由器对象
module.exports=r;

web服务器

//引入自定义的模块user.js
const userRouter=require('./user.js');
//挂载并添加前缀
app.use('/user',userRouter);

五.中间件

用于拦截对路由的请求,最终是为路由服务的。

中间件分为应用级中间件、路由级中间件、内置中间件、第三方中间件、错误处理中间件

(1)应用级中间件

也称为自定义中间件,是一个中间件的函数,一旦拦截就会调用

app.use(要拦截的URL,回调函数)

在回调函数中有三个参数 req、res、next

next表示往后执行,可能是下一个中间件或者路由
:创建web服务器,添加用户数据列表的路由(get /list),响应’这是所有用户的数据’,添加中间件,拦截对URL为 /list的请求,验证用户是否为管理员,如果不是管理员root,则响应’请提供管理员账户’

// 引入第三方express模块
const express=require('express');
// 创建web服务器
const app=express();
// 设置端口
app.listen(8080);

//添加中间件,拦截对URL为 /list的请求
//一旦拦截调用回调函数
//中间件回调函数也有请求对象和响应对象
app.use('/list',(req,res,next)=>{
    //获取查询字符串传递的数据
    console.log(req.query);
    //验证用户是否为管理员
    //如果不是管理员root,则响应'请提供管理员账户'
    if(req.query.uname!=='root'){
        res.send('请提供管理员账户');
    }else{
        //往后继续执行,可能是中间件或者是路由
        next();
    }
});
app.get('/list',(req,res)=>{
    res.send('这是所有用户的数据');
});

(2)路由级中间件

路由器的使用

app.use( URL,引入的路由器);

(3)内置中间件

托管静态资源( html,css , js , img )
浏览器端向服务器端请求静态资源文件,不需要添加路由去寻找斌响应文件,而是将静态资源文件托管到指定的目录下,让浏览器自动去找。

app.use( express.static('目录的路径') )

:创建web服务器,添加静态资源到public目录下,目录中添加登陆的网页login.html,点击提交向服务器发送请求( post /mylogin),创建对应的路由,获取用户和密码,并响应’登陆成功’

const express=require('express');
const querystring=require('querystring');
// 创建web服务器
const app=express();
// 设置端口
app.listen(8080);
// 添加静态资源到public目录下
app.use(express.static('./public'));

app.post('/mylogin',(req,res)=>{
    req.on('data',(chunk)=>{
        let obj=querystring.parse(String(chunk));
        console.log(obj);
        res.send('登录成功');
    });
});
<h2>用户登录</h2>
    <form method="POST" action="/mylogin">
        用户<input type="text" name="uname"><br>
        密码<input type="password" name="upwd"><br>
        <input type="submit">
    </form>

(4)第三方中间件

属于是第三方的模块

body-parse 为例

下载安装:npm install body-parse

通常会伴随express下载安装

//1.引入body-parser模块
const bodyParser=require('body-parser');
//2.使用body-parser中间件将post请求的数据解析为对象
app.use( bodyParser.urlencoded({
    extended:false    //是否使用扩展的qs,true表示使用 false会使用querystring
}) );
//3.在路由中获取数据,格式为对象
req.body

六.mysql 模块

之所以把mysql模块单独拿出来说,是因为mysql模块是常用而且必会

Nodejs 下用于操作mysql数据库的模块

下载安装:npm install mysql

完整的连接

mysql.exe -h127.0.0.1 -P3306 -uroot -p

(1)创建普通连接

mysql.createConnection( )

(2)创建连接池

mysql.createPool( )

(3)执行SQL命令

query(SQL命令,回调函数)

通过回调函数获取结果
:查询出emp数据表里编号为5的所有数据

pool.query('select * from emp where eid=5',(err,result)=>{
    if(err) throw err;
    console.log(result);
});

(4)SQL命令中的占位符

防止SQL注入,将用户提供的值进行过滤,过滤后再替换占位符

pool.query(  'select * from emp where eid=?',['5 or 3=3'],(err,result)=>{
	if(err) throw err;
    console.log(result);
} )
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值