node基础知识

自动安装必要的工具,还将安装Chocolatey的节点

Nodejs概述

Nodejs基于谷歌V8引擎,运行在服务器端的语言,基于JS

对比JS和nodejs

(1)JS运行在客户端浏览器,存在多个浏览器,容易产生兼容性的问题;nodejs是在服务器端只有一个环境,不存在兼容性

(2)两者都有内置(ES)对象、自定义对象、宿主对象(根据执行环境的不同划分)

(3)JS用于网页中的交互效果,nodejs用于服务器的操作,例如web服务器创建,数据库操作,文件操作等

Nodejs的特点:

简单,避免过度设计

单线程逻辑处理

非阻塞的异步I/O处理

事件驱动编程

无锁机制,不会产生死锁

支持数万个并发连接

Nodejs的应用场景

基于社交网络的大规模web应用

不适合CPU密集型的应用(递归、数据加密解密、数据挖掘和数据分析)

Nodejs的执行方式

脚本模式 node 文件目录

交互模式 node 命令 进入交互模式(跟控制台一样的界面),两次CTRL+c或输入.exit退出nodejs

全局对象 全局作用域下的变量就是全局对象下的属性,全局对象下的函数就是全局对象下的方法,可以使用全局对象来访问

Var a = 1;

Global.a-à1

在交互模式下,声明的变量和创建的函数都属于全局下的,可以使用global来访问;在脚本中声明的变量和创建的函数都不属于全局下的,一个文件默认会创建一个独立的作用域,叫做文件(模块)作用域,好处是防止污染全局

在浏览器下,文件中声明的变量或者创建的函数都属于是全局作用域下的,会污染全局

(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的架构

process.platform查看系统

process.env查看当前系统的环境变量

process.version查看当前nodejs的版本号

process.kill()结束某个编号的进程

(3)Buffer对象---缓冲区,一块用于临时存储数据的内存区域,可以存储文件数据、网络上传输的资源(视频、在线直播)

创建buffer var buf = Buffer.alloc(长度,’值’)

将buffer数据转为字符串   buf.toString()

模块 模块就是一个封装好的功能体

Nodejs下模块分为自定义模块、核心模块(官方提供)、第三方模块

(1)自定义模块

在nodejs下,任意一个js文件都是一块模块,文件中的代码默认被一个构造函数所包含

(function(exports,require,module,__filename,__dirname)

{//程序员编写的代码

})

__filename 当前模块的完整路径和文件名称

__dirname 当前模块的完整路径 dir->directory目录

require() 引入模块(文件)require(‘路径’) 同一级目录用 ‘./文件名’

module 指代当前的模块对象

exports 等价于module.exports

module.exports 当前模块导出的对象,包含供其他模块使用的属性和方法

被引入模块的代码:

var a = 1;

function fn(){}

module.exports.recourse = 'a';  //将声明的变量和函数共享出去

module.exports.hanshu = fn;  //共享出去的资源放在一个空的对象中,此时属于给对象添加属性和属性值

要引入模块的文件中的代码:

var obj = require('./second.js'); //引入模块

console.log(obj); //将添加好属性,属性值的对象打印,即可看见模块中共享后的变量和函数

例子:一个文件创建两个函数,另一个文件调用它

function zhouchang(r){

return 2*Math.PI*r; //创建周长函数

}

function mianji(r){

return Math.PI*Math.pow(r,2); //创建面积函数

}

module.exports.zhouchang = zhouchang; //共享

module.exports.mianji = mianji;

var obj = require('./second.js'); //连接外部模块

console.log(obj.zhouchang(10).toFixed(1)); //传递参数打印

console.log(obj.mianji(10).toFixed(1));

模块划分:

以路径开头

不以路径开头

文件模块

Require(‘./路径’)常用于用户自定义的模块,如果后缀名是js,则可以省略

Require(‘url’)用于引入官方提供了的核心模块

目录模块

Require(‘./文件夹名称’)在指定文件夹中找pcakage.json,找不到会引入index.js

Package.json-------{“main”:”xxx.js”}--------规定让程序找到main属性对应的值作为引入的模块

Require(‘文件名’)自动到当前目录下的node_modules中寻找目录模块,如果找不到,会到上一级目录下寻找,直到顶级目录。常用于第三方模块

Npm和包

Npm:包管理工具,随nodejs一起安装

包(package):是一个目录模块,里面包含多个文件,其中有一个文件命名为package.json,是包说明文件,含有包的信息

Npm网址:www.npmjs.com

切换目录:1. cd 完整路径,切换不了先输入 盘符: 然后粘贴完整路径

  2. 在某一文件夹下,按shift单机右键,点击”在此处打开powershell窗口”

npm下载包:输入npm install 包名

生成package.json

Npm init –y  自动生成一个package.json文件,后期使用npm安装的包都会记录到这个文件中,相当于一个笔记本,记录了之前安装过的版本号,后期只需要在package同级目录下输入npm install就会按照记录的版本号自动下载相应版本号的包

  1. 全局函数

一次性定时器

开启:var timer = setTimeout(回调函数,间隔时间毫秒)  当间隔时间到了,执行回调函数

清除:clearTimeout(timer)

周期性定时器

开启:var timer=setInterval(回调函数,间隔时间)  每隔一段时间执行一次回调函数

清除:clearInterval(timer)

例子:打印三次bom后清除定时器:

var count = 0;//变量在外面定义,不然执行一次重新赋值一次

var timer = setInterval(function(){

console.log('bom');

count++;

if(count == 3){

clearInterval(timer);

}

},2000)

立即执行定时器(只能在服务器端执行)

回调函数会放入队列中,当主线程程序执行完,才会立即执行队列的内容

开启:var timer = setImmediate(回调函数);

关闭:clearImmediate(timer)

第二个立即执行函数:process.nextTick(回调函数),,在主程序的末尾执行,先于setImmediate

setImmediate(function(){

console.log('午时已到');-------------- 3

});

process.nextTick(function(){

console.log('立即执行')---------------2

});

console.log('卡擦');---------------------------1

querystring(查询字符串)模块 属于核心模块,由nodejs官方提供,直接引入,无需创建

querystring.parse()将查询字符串格式化为对象

querystring.stringify()将对象转换成查询字符串

URL模块

url.parse()将url格式化为对象

protocol   协议

hostname  服务器域名/IP地址

port       端口号

pathname  文件在服务器上的路径

query      查询字符串

url.format()对象转url  

Const url = require(‘url’);

var obj = {

protocol:'http',

hostname:'172.163.0.224',

port:8080,

pathname:'/admin/login.html',

query:{

uname:'root',

upwd:'123456'}

}

console.log(url.format(obj));

fs模块,,文件系统模块

用于文件的操作,目录的创建、删除、读取,文件的创建、读取、写入、删除。。。

fs.stat(path,callback)

path要查看的文件的路径

callback回调函数,用于获取文件的状态

err查看失败的错误信息

stats文件的状态信息

isDirectory()是否为目录

isFile()是否为文件

fs.statSync(path)

创建目录

fs.mkdir(path,callback)异步 mk-->make

fs.mkdirSync(path)同步

移除目录

fs.rmdir(path,callback)异步 rm-->remove

const fs = require('fs');

var rm = fs.rmdir('test',function(err){

if(err) throw err;

console.log('移除成功!');

})

fs.redirSync(path)同步

const fs = require(‘fs’);

fs.rmdirSync('test');

console.log(2);

读取目录中的内容

fs.readdir(path,callback)异步

const fs = require('fs');

fs.readdir('node_modules',function(err,arr){

if(err) throw err;

console.log(arr);

})

fs.readdirSync(path)同步

const fs = require('fs');

var file = fs.readdirSync('node_modules');

console.log(file);

返回数组形式

创建并写入内容文件,多次执行,会清空之前的内容重新写入

fs.writeFile(path,content,callback)

fs.writeFileSync(path,content)

const fs = require('fs');

fs.writeFile('writefile.txt','哈哈',function(err){

if(err) throw err;

console.log('创建成功');

})

追加写入

appendFile(path,content,callback)

appendFileSync(path)

const fs = require('fs');

fs.appendFile('writefile.txt','hehe',function(err){

if(err) throw err;

console.log('创建成功');

})

读取文件

fs.readFile(path,callback) 格式为buffer,必须tostring()

fs.readFileSync()

如果想一次添加很多数据,先创建数组,content传递数组名即可

const fs = require('fs');

var arr = ['tom','jerry','lily'];

fs.readFile('writefile.txt',function(err,data){

if(err) throw err;

console.log(data.toString());

})

删除文件

fs.unlink(path,callback(err));

fs.unlink('writefile.txt',function(err){

if(err) throw err;

})

fs.unlinkSync(path);

判断文件是否存在

fs.existsSync(path) true / false

console.log(fs.existsSync('writefile.txt'));

同步和异步:

同步:方法调用后,必须等待方法调用结束才能继续后边的任务;通过返回值获取结果

异步:方法调用后无需等待结束,直接执行后续的代码,整个过程不会阻碍后边的任务;通过回调函数获取结果

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

  1. 通用头信息(General)

Request URL:请求的URL,对应浏览器地址栏的内容

Request Method:请求的方法,GET/POST。。。,获取内容的方式

Status Code:相应的状态码,(200、404等)

1**:正在请求,没有结束

2**:成功

3**:相应的重定向,跳转到另一个URL;通常结合相应头信息中Location一起使用

4**:客户端错误

5**:服务器错误(瘫痪)

Remote Address:服务器IP地址及端口号

  1. 响应头信息(ResponseHeaders)

Connection:连接的方式,keep-alive持续连接

Content-type:响应的文件类型

Content-Length:响应的文件长度

Transfer-Encoding:传输方式 chuncked分段传输

Content-Encoding:压缩模式 gzip压缩

Location:当响应重定向的时候,跳转的URL

  1. 请求头信息(RequestHeaders)

Accept:客户端接受的文件类型有哪些

Accept-Encoding:客户端接受的压缩形式

User-Agent:客户端发请求使用的浏览器

  1. 请求主体

可有可无,客户端向服务器端传递的数据

http模块

既可以模拟浏览器向web服务器发请求,也可以创建web服务器

  1. 模拟浏览器

http.get(url,callback)

get 请求的方法

callback 回调函数,用于获取服务器端的相应

res 响应的对象

statusCode 响应的状态码

res.on(‘data’,function(buf){buf.toString()})

//引入http

const http = require('http');

//模拟浏览器向web服务器发请求

//get:请求的方法,参数1:请求的URL,参数2:获取服务器端的响应

http.get('http://www.baidu.com/',function(res){

//res为相应的内容,格式为对象

console.log(res);

//获取响应的状态码

console.log(res.statusCode);----200

//响应数据。通过事件获取:当有数据传输的时候,自动触发这个事件

res.on('data',function(buffer){

console.log(buffer.toString());//获取到所有数据(html标签)

});

})

  1. 创建web服务器

var server = http.createServer() 创建本地web服务器

server.listen(8080) 设置web服务器端口号,监听端口变化

const http = require('http');

var server = http.createServer();//创建服务器

server.listen(8080);//设置web服务器端口号

server.on('request',function(req,res){//当有请求发生,自动触发事件。通过回调函数来获取请求和做出响应

//req: 请求的对象、res: 响应的对象

console.log(req.url,req.method);

//设置响应的状态码和头信息,可以不设置

res.writeHead(200,{

Server:'web'

})

//设置响应的内容,发送到浏览器

res.write('hello world');

//结束响应

res.end();

})

当请求的url最后边是login,回应已进入login,如果是study,跳转到百度

const http = require('http');

var server = http.createServer();//创建服务器

server.listen(8080);//设置web服务器端口号

server.on('request',function(req,res){

if(req.url == '/login'){

res.write('已进入login')

}else if(req.url == '/study'){

res.writeHead(302,{

Location:'http://www.baidu.com'

})

}

res.end();

})

1.express框架 基于nodejs的快速、开放、极简的web开发框架。www.expressjs.com.cn

//引入express

const express = require('express');

//创建服务器

var server = express();

//设置端口号

server.listen(8080);

路由:当浏览器向web服务器发送请求,web服务器根据请求的方法和请求的url来做出响应

三要素:请求方法、请求的url、响应(回调函数)

响应的对象(res)

send()  响应的内容,只能响应一次;

sendFile()  响应文件,必须使用绝对路径(__dirname+’html文件名’)

redirect()  响应的重定向

请求的对象(req)

req.method  请求的方法

req.url  请求的URL

req.headers  请求的头信息

req.query  获取请求时查询字符串传递的数据,并格式化为对象

server.get('/list',function(req,res){

res.sendFile(__dirname+'/index.html'); //响应html文件到浏览器

})

post和get传递数据

post请求是通过表单提交传递数据,服务器端是通过事件的形式获取数据

req.on(‘data’,function(buf){buf是获取的数据,要toString(),需要借助查询字符串模块格式化为对象})

get请求以查询字符串形式传递数据,服务器端使用req.query获取数据,结果是对象。查询字符串传递容易被浏览器缓存,而post传递数据不会出现在地址栏。

<h2>请注册</h2>

<form method = "post" action = "/myindex">

用户:<input type="text" name="uname"><br>

密码:<input type="text" name="upwd"><br>

手机:<input type="text" name="phone"><br>

<input type="submit">

</form>

const express = require('express');

var server = express();

const querystring = require('querystring');

server.listen(8080);

server.get('/index',function(req,res){

res.sendFile(__dirname+'/index.html');

req.on('data',function(buf){ //获取post请求传递的数据

console.log(buf.toString());

});//以事件的形式。当有数据传输自动触发事件

res.send('注册成功');

})

server.post('/myindex',function(req,res){

//console.log(req.query);

res.send('注册成功!!!!');

})

使用路由传递数据——路由传参

设置路由中接收的名称

server.get('/detail/:lid',function(req,res){

console.log(req.params);//接收路由传递的数据,格式为对象

res.send('成功');

})

路由器  路由的使用过程中,不同的模块可能出现相同的URL,把同一个模块下的所有路由放到一个容器,这个容器就是路由器最终要引入到web服务器下才能使用。

const express = require('express');

var router = express.Router();//使用express创建空的路由器,返回对象模式

router.get('/list',function(req,res){

res.send('这是商品模块下的列表');

});//给路由器添加路由,商品模块下的所有路由都添加在这个路由器中

module.exports = router; //导出路由器

const express = require('express');

var server = express();

server.listen(8080);

const productRouter = require('./product_router.js');

 //引入商品路由器

//商品模块路由

server.use('/product',productRouter); //使用商品路由器,挂载到/product下,访问形式是/product/list参数1:挂载的位置,参数2:使用的路由器

中间件  过滤器,作用是为主要的业务逻辑服务

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

  1. 应用级(自定义)中间件  每个中间件都是一个函数

Server.use(path,function(req,res,next){})

const express = require('express');

var server = express();

server.listen(8080);

//使用中间件验证注册,参数1:给哪个url路由使用,如果为空,表示会给所有的路由使用;参数2:中间件函数;获取请求,以及做出响应

server.use('path',function(req,res,next){//如果path为空,则对所有路由过滤

console.log('验证数据是否为空');

next();//会执行下一个中间件或者路由

})

server.get('/reg',function(req,res){

res.send('注册成功');

});

server.get('/list',function(req,res){

res.send('这是商品列表');

})

  1. 路由级中间件

Server.use(path,路由器)

  1. 内置中间件

在express4下只保留了一个内置中间件

server.use(Express.static('目录’));

把静态资源托管到指定的目录,如果浏览器请求静态资源,自动到该目录下查找

  1. 第三方中间件

Server.use(body.urlencoded({extended:false}))

创建hehe.js文件,创建web服务器,托管静态资源到public下,在public下创建login.html,使用浏览器请求该文件,点击按钮,向服务器发请求

const express = require('express');

const bodyp = require('body-parser');

var server = express();

server.listen(8080);

server.use(express.static('public'));

server.use(bodyp.urlencoded({ //将post请求的数据格式化为对象

extended:false//不使用扩展的qs模块,而是使用querystring模块,格式化为对象

}));

server.post('/mylogin',function(req,res){

console.log(req.body); //格式为对象

res.send('登录成功');

})

<h2>这是静态文件</h2>

<form method="post" action="mylogin">

用户名:<input type="text" name="uname"><br>

密码:<input type="passward" name="pwd"><br>

<input type="submit">

</form>

连接MySQL

var connection = mysql.createConnection({

host:’127.0.0.1’,

port:3306,

user:’root’,

password:’’,

database:’数据库名’ //连接后使用的数据库

});//创建连接对象

connection.connect() //建立连接

connection.query(sql,callback) sql是要执行的sql语句,callback回调函数,用于获取sql语句的结果

connection.end() 关闭连接

const mysql = require('mysql'); //引入MySQL模块

var connection = mysql.createConnection({//创建连接对象

host:'127.0.0.1',

port:'3306',

user:'root',

password:'',

database:'dang'//连接后使用的数据库

})

connection.connect();//建立连接

connection.query('select * from book',function(err,result){//err可能产生的错误,result执行的结果

if(err) throw err;

console.log(result);

});

//关闭连接

connection.end();

连接池

var pool = mysql.createPool();

//引入MySQL模块

const mysql = require('mysql');

//创建连接池对象

var pool = mysql.createPool({

host:'127.0.0.1',

port:'3306',

user:'root',

password:'',

database:'dang',//连接后使用的数据库

connectionLimit:20//设置连接池大小,默认是15

})

pool.query('select * from book',function(err,result){

if(err) throw err;

console.log(result);

});

插入数据(非正规sql语句,只适用于插入)

var obj = { //对象中的属性名必须和表中的列名一致

bid:10,

title:'gangtie',

author:'dff',

price:10,

publish:'sha',

pubTime:'2020-03-01'

}

pool.query('insert into book set ?',[obj],function(err,result){ //?代表占位符

if(err) throw err;

console.log(result);

})

修改数据

pool.query('update book set title=? where bid=?',['summer',10],function(err,result){

if(err) throw err;

console.log(result);

});

删除数据

pool.query('delete from book where bid=6',function(err,result){

if(err) throw err;

console.log(result);

});

综合案例:

const express = require('express');

const mysql = require('mysql');

var server = express();

server.listen(8080);

server.use(express.static('public'));//托管静态资源到public

var pool = mysql.createPool({//创建数据池

host:'127.0.0.1',

port:3306,

user:'root',

password:'',

database:'dang'

})

server.get('/add',function(req,res){//根据表单提交创建对应路由

var obj = req.query;//获取浏览器传递的数据

console.log(obj);

pool.query('insert into book set ?',[obj],function(err,result){

if(err) throw err;

if(result.affectedRows > 0){

res.send({code:200,msg:'add suc'});

}

})

});

<h2>添加数据</h2>

<form method="get" action="/add">

<!-- ID:<input type="text" name="bid"><br> -->

标题:<input type="text" name="title"><br>

作者:<input type="text" name="author"><br>

价格:<input type="text" name="price"><br>

出版社:<input type="text" name="publish"><br>

出版时间:<input type="text" name="pubTime"><br>

<input type="submit" name="">

</form>

基础项目用户路由器文件

//用户路由器

const express = require('express');

const pool = require('../pool.js')

var router = express.Router();

//用户注册

router.get('/reg',function(req,res){

var obj = req.query;//获取get请求的数据

if(obj.uname==''){//检测值是否为空

res.send({code:401,msg:'uname required'});

return;//阻止往后执行

}

if(obj.upwd==''){

res.send({code:402,msg:'upwd required'});

return;

}

if(obj.phone==''){

res.send({code:403,msg:'phone required'});

return;

}

if(obj.email==''){

res.send({code:401,msg:'email required'});

return;

}

pool.query('insert into user set ?',[obj],function(err,result){

if(err) throw err;

console.log(result);

if(result.affectedRows>0){

res.send({code:200,msg:'suc'});

}

})

})

//用户登录

router.post('/login',function(req,res){

var obj = req.body;

//console.log(obj);

if(obj.uname ==''){

res.send({code:401,msg:'required'});

return;

}

if(obj.upwd == ''){

res.send({code:402,msg:'required'});

return;

}

pool.query('select * from user where uname=? and upwd=?',[obj.uname,obj.upwd],function(err,result){

if(err) throw err;

if(result.length>0){

res.send({code:200,msg:'login suc'});

}else{

res.send({code:301,msg:'login err'});

}

});//查询用户表中是否含有输入的数据

})

//用户修改

router.get('/update',function(req,res){

var obj = req.query;

var c = 400;//初始化状态码

for(var key in obj){//遍历对象属性

c ++;

//判断属性值是否为空

if(!obj[key]){

res.send({code:c,msg:key+' required'});

return;

}

}

pool.query('update user set uname=?,gender=?,email=?,phone=? where uid=?',[obj.uname,obj.gender,obj.email,obj.phone,obj.uid],function(err,result){

if(err) throw err;

if(result.affectedRows>0){//判断是否修改成功

res.send({code:200,msg:'update suc'})

}else{res.send({code:301,msg:'update err'});}

})

})

//用户检索

router.get('/detail',function(req,res){

var obj = req.query;

if(!obj.uid){

res.send({code:401,msg:'ID required'});

res.end();

}

pool.query('select * from user where uid=?',[obj.uid],function(err,result){

if(err) throw err;

res.send(result);

})

})

//用户删除

router.get('/delete',function(req,res){

var obj = req.query;

if(!obj.uid){

res.send({code:401,msg:'ID required'});

return;

}

pool.query('delete from user where uid=?',[obj.uid],function(err,result){

if(err) throw err;

if(result.affectedRows>0){

res.send({code:200,msg:'delete suc'});

}else{

res.send({code:301,msg:'delete err'});

}

})

})

//查看用户列表

router.get('/list',function(req,res){

var obj = req.query;

if(!obj.pnum){obj.pnum = 1;}

if(!obj.count){obj.count = 3;}

//将传递的值转为整形

obj.pnum=parseInt(obj.pnum);

obj.count=parseInt(obj.count);

//计算开始查询的值

var start=(obj.pnum-1)*obj.count;

pool.query('select * from user limit ?,?',[start,obj.count],function(err,result){

if(err) throw err;

res.send(result);

})

})

module.exports = router;//导出路由器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

光影少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值