Node.js学习
Node.js ⭐⭐⭐⭐
Node.js是什么
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效
非阻塞式I/O
事件驱动
基于Chrom V8引擎的js运行环境
- V8 引擎是 Chrome 浏览器在用的 JavaScript 引擎. V8 引擎由 C++ 实现, 支持跨平台,
进程和线程
- 线程: 程序执行流的最小单元。程序代码在其中被 CPU 依次处理. 在一条线程中, 同一时间, 只有一段代码被被执行, 或等待被执行.
安装Node.js
npm
-
定义
- npm 的第二种含义是一个命令行工具
- npm 是基于 nodejs 开发出来的包管理工具,所以用 npm 时,要先安装 node
-
npm指令
- npm -v:查看npm版本。
- npm init:初始化后会出现一个package.json配置文件。可以在后面加上-y ,快速跳过问答式界面。
- npm install:会根据项目中的package.json文件自动下载项目所需的全部依赖。---生成node_modules文件夹
- npm install 包名 --save-dev(npm install 包名 -D):安装的包只用于开发环境,不用于生产环境,会出现在package.json文件中的devDependencies属性中。
- npm install 包名 --save(npm install 包名 -S):安装的包需要发布到生产环境的,会出现在package.json文件中的dependencies属性中。
- npm --help:查看npm帮助命令。
- npm update 包名:更新指定包。
- npm uninstall 包名:卸载指定包。
- npm config list:查看配置信息。
- npm info 指定包名:查看远程npm上指定包的所有版本信息。
- npm config set registry https://registry.npm.taobao.org: 修改包下载源,此例修改为了淘宝镜像。
- npm root:查看当前包的安装路径。
REPL交互解释器
读取 - 读取用户输入,解析输入的 Javascript 数据结构并存储在内存中。
执行 - 执行输入的数据结构
打印 - 输出结果
循环 - 循环操作以上步骤直到用户两次按下 ctrl-c 按钮退出。
REPL 命令
- ctrl + c - 退出当前终端。
- ctrl + c 按下两次 - 退出 Node REPL。
- ctrl + d - 退出 Node REPL.
- 向上/向下 键 - 查看输入的历史命令
- tab 键 - 列出当前命令
- .help - 列出使用命令
- .break - 退出多行表达式
- .clear - 退出多行表达式
全局
全局对象
global:类似客户端中的window
process:获取进程相关信息
console:类似客户端中的console
全局函数
setInterval()
clearInerval()
setTimeout()
clearTimeout()
模块机制
模块分类
-
核心模块
Node.js 自带的原生模块. 比如, http, fs, url. 其分为 C/C++ 编写的和 JavaScript 编写的两部分. C/C++ 模块存放在 Node.js 源代码目录的 src/ 目录下. JavaScript 模块存放在 lib/ 目录下
-
fs模块--文件系统
-
读取文件--fs.readFile('file',(err,data)=>{...})
fs.readFile('input.txt', function (err, data) {
if (err) {
return console.error(err);
}
console.log("异步读取: " + data.toString());
});
异步地读取文件的全部内容 -
打开文件--fs.open(path,callback)
参数说明:
path - 文件的路径。
flags - 文件打开的行为。
mode - 设置文件模式(权限),文件创建默认权限为 0666(可读,可写)。
callback - 回调函数,带有两个参数如:callback(err, fd)
eg: var fs = require("fs");
console.log("准备打开文件!");
fs.open('input.txt', 'r+',(err, fd)=>{
if (err) {
return console.error(err);
}
console.log("文件打开成功!");
}); -
获取文件信息--fs.stat(path, callback)
参数:
path - 文件路径。
callback - 回调函数,带有两个参数如:(err, stats), stats 是 fs.Stats 对象 stats类中的方法
stats.isFile()---是文件返回 true,否则返回 false;
stats.isDirectory()--是目录返回true,否则返回false; -
写入文件--fs.writeFile(file, data[, options], callback)
参数:
file - 文件名或文件描述符
data - 要写入文件的数据
options - 该参数是一个对象
callback - 回调函数,回调函数只包含错误信息参数(err) -
读取文件--fs.read(fd, buffer, offset, length, position, callback)
参数
fd - 通过 fs.open() 方法返回的文件描述符。
buffer - 数据写入的缓冲区。
offset - 缓冲区写入的写入偏移量。
length - 要从文件中读取的字节数。
position - 文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。
callback - 回调函数,有三个参数err, bytesRead, buffer,err 为错误信息, bytesRead 表示读取的字节数,buffer 为缓冲区对象。 -
删除文件--fs.unlink(path, callback)
参数
参数使用说明如下:
path - 文件路径。
callback - 回调函数,没有参数。
var fs = require("fs");console.log("准备删除文件!");
fs.unlink('input.txt', function(err) {
if (err) {
return console.error(err);
}
console.log("文件删除成功!");
}); -
创建目录--fs.mkdir(path[, options], callback)
参数
参数使用说明如下:
path - 文件路径。
options 参数可以是:
recursive - 是否以递归的方式创建目录,默认为 false。
mode - 设置目录权限,默认为 0777。
callback - 回调函数,没有参数。
var fs = require("fs");
// tmp 目录必须存在
console.log("创建目录 /tmp/test/");
fs.mkdir("/tmp/test/",function(err){
if (err) {
return console.error(err);
}
console.log("目录创建成功。");
}); -
读取目录--fs.readdir(path, callback)
参数
参数使用说明如下:
path - 文件路径。
callback - 回调函数,回调函数带有两个参数err, files,err 为错误信息,files 为 目录下的文件数组列表。
var fs = require("fs");console.log("查看 /tmp 目录");
fs.readdir("/tmp/",function(err, files){
if (err) {
return console.error(err);
}
files.forEach( function (file){
console.log( file );
});
}); -
删除目录--fs.rmdir(path, callback)
参数
参数使用说明如下:
path - 文件路径。
callback - 回调函数,没有参数。
var fs = require("fs");
// 执行前创建一个空的 /tmp/test 目录
console.log("准备删除目录 /tmp/test");
fs.rmdir("/tmp/test",function(err){
if (err) {
return console.error(err);
}
console.log("读取 /tmp 目录");
fs.readdir("/tmp/",function(err, files){
if (err) {
return console.error(err);
}
files.forEach( function (file){
console.log( file );
});
});
});
-
-
querystring模块--查询字符串
-
querystring.parse(str)
str 要解析的 URL 查询字符串。
-
将 URL 查询字符串 str 解析为键值对的集合
查询字符串 'foo=bar&abc=xyz&abc=123' 会被解析为{
foo: 'bar',
abc: ['xyz', '123']
}
querystring.parse() 方法返回的对象不是原型地继承自 JavaScript 的 Object。 这意味着典型的 Object 方法如 obj.toString()、obj.hasOwnProperty() 等都没有被定义并且不起作用。上面所诉是对象实例上的方法无法使用,但对象Object方法可以部分使用
-
-
querystring.stringify(obj)
方法通过遍历对象的自身属性从给定的 obj 生成 URL 查询字符串
-
方法通过遍历对象的自身属性从给定的 obj 生成 URL 查询字符串
querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' });
// 返回 'foo=bar&baz=qux&baz=quux&corge='querystring.stringify({ foo: 'bar', baz: 'qux' }, ';', '😂;
// 返回 'foo:bar;baz:qux'
-
-
querystring.decode()
- querystring.decode() 函数是 querystring.parse() 的别名
-
querystring.encode()
- querystring.encode() 函数是 querystring.stringify() 的别名
-
-
assert模块--断言
-
用途
- 通常用来对代码进行校验,若出错则阻止程序运行,并抛出一个错误
-
使用方式
- 通常可以在一个模块或函数的每个阶段使用assert,或者在对函数传参进行assert校验,以保证代码运行的正确性。
-
方法
-
assert.deepStrictEqual(actual, expected)深度比较,判断成员和值是否相等
assert.deepStrictEqual在校验对象或数组时比较有用。
-
-
-
ctrpto模块--加密
-
用途
- 模块提供了加密功能,其中包括了对 OpenSSL 散列、HMAC、加密、解密、签名和验证函数的一整套封装
-
使用方法
-
MD5加密
- let hash =crypto.createHash("MD5").update(req.body.password);
- req.body.password=hash.digest("hex")
-
-
-
url模块--网址处理和解析
-
方法
-
旧版方法--url字符串
-
url.parse(urlString)
url.parse() 方法接受 URL 字符串,解析并返回 URL 对象。
var a = url.parse('http://localhost:8080/one?a=index&t=article');
//输出结果:
{
protocol : 'http' ,
auth : null ,
host : 'localhost:8080' ,
port : '8080' ,
hostname : 'localhost' ,
hash : null ,
search : '?a=index&t=article',
query : 'a=index&t=article',
pathname : '/one',
path : '/one?a=index&t=article',
href : 'http://localhost:8080/one?a=index&t=article'
} -
共有方法和属性
-
url.resolve(from, to)--将获取url路径后缀前面的文件进行替换
url.resolve() 方法以类似于 Web 浏览器解析锚标记 HREF 的方式解析相对于基本 URL 的目标 URL
const url = require('url');
url.resolve('/one/two/three', 'four'); // '/one/two/four'
url.resolve('http://example.com/', '/one'); // 'http://example.com/one'
url.resolve('http://example.com/one', '/two'); // 'http://example.com/two' -
url.hash--获取和设置 URL 的片段部分。
const myURL = new URL('https://example.org/foo#bar');
console.log(myURL.hash);
// 打印 #bar -
url.host--获取和设置 URL 的主机部分
const myURL = new URL('https://example.org:81/foo');
console.log(myURL.host);
// 打印 example.org:81 -
url.hostname--获取和设置 URL 的主机名部分
const myURL = new URL('https://example.org:81/foo');
console.log(myURL.hostname);
// 打印 example.org -
url.href--获取和设置序列化的 URL
const myURL = new URL('https://example.org/foo');
console.log(myURL.href);
// 打印 https://example.org/foo -
url.protocol--获取和设置 URL 的协议部分
const myURL = new URL('https://example.org');
console.log(myURL.protocol);
// 打印 https:
-
-
-
新版方法--URL对象
-
new URL(input[, base])
input
要解析的绝对或相对的输入 URL。 如果 input 是相对的,则需要 base。 如果 input 是绝对的,则忽略 base。
base| 如果 input 不是绝对的,则为要解析的基本 URL。 -
url.password--获取和设置 URL 的密码部分
-
url.username--获取和设置 URL 的用户名部分
const myURL = new URL('https://abc:xyz@example.com');
console.log(myURL.username);
// 打印 abc
-
-
-
-
http模块--搭建HTTP服务
-
搭建网络
-
1.创建服务器对象
const http = require('http');
const server = http.createServer(); -
2.创建请求处理函数
-
第一种:通过request 事件处理函数
//通过createServer的方式创建服务对象
let app = http.createServer();
// console.log(app)
app.on('reqeust',function(req,res) { console.log(123)
}) -
第二种:创建服务端对象通过回调函数的方式
let app=http.createServer((require,response)=>{
require.write('hello world');
})
console.log(app);
-
-
3 设置服务监听
通过listen的方式设置服务监听
listen接受四个参数:
server.listen(port [, host] [,backlog] [, callback])
prot 必需的 监听的端口号
host 可选的 监听指定的地址(一般省略)
backlog 可选, 参数是一个指定等待客户端连接的最大数量, 默认511( 一般不使用)
callback 可选, 用于在服务器监听启动成功后执行的回调函数
-
-
请求和响应(在请求处理函数里)
-
request
-
请求属性
-
method属性--请求方法GET或POST
-
url属性--请求路径(路径和网页图标)
url 属性值为客户端发送请求时使用URL参数字符串
打印出两条信息一个是请求的路径,第二个是请求网页标题的小图标 -
header属性--客户端发送的请求头
-
-
-
response
-
响应属性
-
writeHead : 设置有状态码的响应头信息
-
参数
- statusCode : 第一个参数,必须传递,执行一个http状态码
- reasonPhrase : 第二个参数可选,就是对状态码的描述信息,是一个字符串,一般不会用到
- header : 第三个参数可选,参数值是一个对象,用来配置响应头信息
-
响应头的常用属性
-
-
setHeader : 设置单个响应头字段
-
write : 发送响应数据
-
end : 结束响应
-
-
-
-
-
path模块--路径操作
比如提取路径、后缀,拼接路径等
-
方法
const path = require('path')
const str = '/root/a/b/1.txt'-
path.dirname(str)获取文件目录---当前文件的上一级目录
path.dirname('asdf/quux');
// 返回: 'asdf' -
path.basename(str) 获取文件名
-
path.extname(str)获取文件后缀
path.extname('index.coffee.md');
// 返回: '.md' -
path.join([...paths])规范化生成的路径
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
// 返回: '/foo/bar/baz/asdf' -
path.parse(path)将地址转换为对象
path.parse('/home/user/dir/file.txt');
// 返回:
// { root: '/',
// dir: '/home/user/dir',
// base: 'file.txt',
// ext: '.txt',
// name: 'file' }
-
-
-
util模块--提供常用函数
-
方法
-
util.callbackify(asyncFunction| promise)
将 async 异步函数(或者一个返回值为 Promise 的函数)转换成遵循异常优先的回调风格的函数,例如将 (err, value) => ... 回调作为最后一个参数。 在回调函数中,第一个参数为拒绝的原因(如果 Promise 解决,则为 null),第二个参数则是解决的值。
-
util.isArray(object)
如果给定的参数 "object" 是一个数组返回 true,否则返回 false
var util = require('util');
util.isArray([])
// true
util.isArray(new Array)
// true
util.isArray({})
// false -
util.isRegExp(object)
如果给定的参数 "object" 是一个正则表达式返回true,否则返回false。
var util = require('util');util.isRegExp(/some regexp/)
// true
util.isRegExp(new RegExp('another regexp'))
// true
util.isRegExp({})
// false -
util.isDate(object)
如果给定的参数 "object" 是一个日期返回true,否则返回false。
var util = require('util');
util.isDate(new Date())
// true
util.isDate(Date())
// false (without 'new' returns a String)
util.isDate({})
// false -
util.inspect(object,[showHidden],[depth],[colors])
是一个将任意对象转换 为字符串的方法,通常用于调试和错误输出。它至少接受一个参数 object,即要转换的对象。
参数:
showHidden 是一个可选参数,如果值为 true,将会输出更多隐藏信息
depth 表示最大递归的层数,如果对象很复杂,你可以指定层数以控制输出信息的多 少
var util = require('util');
function Person() {
this.name = 'byvoid';
this.toString = function() {
return this.name;
};
}
var obj = new Person();
console.log(util.inspect(obj));
console.log(util.inspect(obj, true));
运行结果:
Person { name: 'byvoid', toString: [Function] }
Person {
name: 'byvoid',
toString:
{ [Function]
[length]: 0,
[name]: '',
[arguments]: null,
[caller]: null,
[prototype]: { [constructor]: [Circular] } } } -
util.inhrits(constructor, superConstructor)
是一个实现对象间原型继承的函数
-
-
-
os模块--提供操作系统得方法和属性
-
-
第三方模块
别人编写的模块, 通过包管理工具, 比如 npm, yarn, 可以将其从网络上引入到本地项目, 供己使用 ,有express,axios,mysql之类的模块
-
文件模块
开发人员在本地写的模块. 加载时通过相对路径, 绝对路径来定位模块所在位置
使用模块
-
创建 & 导出模块
- module.exports={...} --导出对象
- exports.name=value--导出属性或变量
-
引入模块
-
require函数
-
require 的路径参数
-
相对路径: ./ 开头 或 ../ 开头
var haha = require('./modules/haha');
按 js 文件来执行(先找对应路径当中是否有 haha.js 文件, 有就加载)
按 json 文件来解析(若上面的 js 文件找不到时,则找对应路径当中的 haha.json 文件来加载)
按照预编译好的 C++ 模块来执行(还没有, 寻找对应路径当中的 haha.node 文件来加载)
若参数字符串为一个目录的路径, 就是说 haha 为一个目录, 则先查找该文件夹下的 package.json 文件,然后再加载该文件当中 main 字段所指定的入口文件. 若 package.json 文件当中没有 main 字段,或者根本没有 package.json 文件,则再默认查找该文件夹下的 index.js 文件, 并作为模块来载入. -
绝对路径: / 开头
-
模块名 (例如: http, fs, url)
var haha = require('haha');
1.如果 haha 是 Node.js 核心模块就直接加载.2.如果是第三方模块, 则依次从当前目录中的 node_modules 目录, 父级目录中的 node_modules 目录, 一直到根目录下的 node_modules 目录下去查找 haha 的所在. 若有两个同名文件,则遵循就近原则。优先引入目录顺序靠前的模块.
3.如果找到的 haha 为一个目录, 则先查找该文件夹下的 package.json 文件,然后再加载该文件当中 main 字段所指定的入口文件. 若 package.json 文件当中没有 main 字段,或者根本没有 package.json 文件,则再默认查找该文件夹下的 index.js 文件, 并作为模块来载入.
-
-
GET/POST请求
获取GET请求内容
由于GET请求直接被嵌入在路径中,URL完整的请求路径,包括了?后面的部分,因此你可以手动解析后面的内容作为GET的参数,Nodejs的url模块中的parse函数提供了这个功能
-
代码
const http = require('http');
const net = require('net');
const url = require('url');
const util = require('util');http.createServer((req,res)=>{
res.write(util.inspect(url.parse(req.url,true)));
//利用url模块去解析客户端发送过来的URL
res.end(util.inspect(url.parse(req.url,false)));
}).listen(8080);
获得POST请求内容
POST请求的内容全部都在请求体中,http.ServerRequest并没有一个属性内容为请求体,原因是等待请求体传输可能是一件耗时的工作。譬如上传文件。恶意的POST请求会大大消耗服务器的资源。所以Nodejs是不会解析请求体,当你需要的时候,需要手动来做
-
代码
const http = require('http');
const net = require('net');
const url = require('url');
const util = require('util');
//querystring用于处理URL中的查询字符串
const querystring = require('querystring');http.createServer((req,res)=>{
var posr = '';
req.on('data',(chunk)=>{
post+=chunk;
});
res,on('end',()=>{
//将字符串变为json的格式
post = querystring.parse(post);
//向前端返回字符串
res.end(util.inspect(post));
});
})
mysql
一:安装mysql引用模块
-
npm install mysql--在项目文件安装
-
var mysql = require('mysql');
-
npm数据库操作
-
登录数据库
mysql -u 用户名 -p
-》回车输入 密码
-
显示数据库
- show databases;
-
创建数据库
- create database 数据库名;
-
进入某个数据库
- use 数据库名;
-
显示所有表
- show tables;
-
查询表
- select * from 表名;
-
创建表
CREATE TABLE IF NOT EXISTS
表名
(
id
INT UNSIGNED AUTO_INCREMENT,
username
VARCHAR(100) NOT NULL,
password
CHAR(32) NOT NULL,
PRIMARY KEY (id
)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; -
给表创建字段
-
alter table 表名 add 字段名 字段类型(长度)
alter table admin add password varchar(255)
-
-
查看表结构
- describe 表名
-
二:建立连接和关闭连接
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
port : 3306,
database : 'node',
user : 'root',
password : 'root'
});
connection.connect(function(err) {
if(err) {
console.log("连接失败");
}else{
console.log("连接成功");
}
});
connection.end(function(err) {
if(err) {
console.log("关闭连接失败");
}else{
console.log("关闭连接成功");
}
});
-
(1)createConnection方法创建连接对象
语法:var connection = mysql.createConnection(options); options为参数,是一个对象或者url字符串,用于指定该连接所用的各种选项。当为对象时一些属性有:host,port,user,password,database,multipleStatements,以上是常用的
-
(2)用对象的connect方法建立连接
语法:connection.connect(function(err) { *** }); function为建立连接操作结束后的回调函数,参数为连接失败时触发的错误对象
-
(3)关闭连接,connection对象的end方法和destory方法
-
区别
两种方法的区别:end方法可以使用一个参数,指定关闭操作结束时的回调函数。destory没有参数。end方法在关闭连接之前将所有查询操作执行完毕,destory直接关闭连接。
-
三:执行数据处理
console.log(err);
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
port : 3306,
database : 'node',
user : 'root',
password : 'root'
});
connection.connect(function(err) {
if(err) { console.log("连接失败"); }
else{ console.log("连接成功"); }
})
var query = 'insert into user set ?';
connection.query(query,{
username : 'node',
password : 'node',
sex : 'woman'
},function(err,results) {
if(err) { console.log("插入失败"); }
else{ console.log("插入成功");
console.log(results.insertId);
connection.query('select * from user where username = "node"',function(err,results) {
console.log("查询成功");
console.log(results);
})
}
})
-
通过connection的query方法统一执行增删改查的操作
语法:connection.query(sql,[parameters],[callback]); 其中sql为必须指定参数,为字符串,为需要执行的sql表达式。parameters为对象或者数组,存放sql参数所用到的所有参数的参数值。callback为执行操作结束后的回调函数。指定方法function(err,results){ *** } err为执行操作失败时触发的错误对象,results为一个对象,代表sql操作的执行结果。
-
查询数据
- select* from 表名 [WHERE 字段名="值" AND/OR 条件] [ORDER BY 字段名 ASC/DESC] [LIMIT start,len]
-
新增数据
- insert into 表名(字段名1,字段名2..) VALUES("值1","值2"...)
-
修改数据
- update 表名 set 字段名="值"[,字段名2="值2"...] [WHERE 条件]
-
删除数据
- delete from 表名 [WHERE 条件]
-
四:创建连接池
- .......
express框架
特性
- 可以设置中间件响应http请求
- 定义了路由来响应不同的http请求
- 可以通过向模板传递参数来动态渲染HTML页面
安装和使用
-
npm创建项目文件夹:mkdir 文件夹名
-
初始化项目:npm init---创建项目配置文件(package.json)
{
"name": "ex",//文件夹名
"version": "1.0.0", //版本
"description": "", // 描述
"main": "app.js",//入口文件(entry point)
"scripts": { //可运行命令
"test": "echo "Error: no test specified" && exit 1",
//下面黑色内容为执行
“start”:"node app.js"
},
"author": "lht",//作者
"license": "ISC",
“dependencies”:{//生成环境依赖包
"express":"^4.17.1"
},
“devDependencies”:{//开发环境依赖包
“babel“:”^4.17.1“
}
} -
安装express:npm i express -S
--S 将依赖包写入到生成环境依赖,
--D 将依赖包写入到开发环境依赖 -
express框架使用
-
一:导入express框架
let express=require("express")
-
二:创建一个express程序
let app =express();
-
三:创建web服务器
app.listen(port,[callback])
-
四:获取http请求
app.get/post/put/datale(path,(req,res)=>{...})
查/真/改/删
-
app对象---顶层express方法创建
let app=express();
-
路由HTTP请求
- app.get()
- app.post()
- app.put()
-
配置中间件
- app.route(path)
-
注册模板引擎
- app.engine
-
渲染HTML视图
- app.render
响应对象和请求对象
-
Request 对象
request 对象表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性。
- req.app:当callback为外部文件时,用req.app访问express的实例
- req.baseUrl:获取路由当前安装的URL路径
- req.body / req.cookies:获得「请求主体」/ Cookies
- req.fresh / req.stale:判断请求是否还「新鲜」
- req.originalUrl:获取原始请求URL
- req.params:获取路由的parameters
- req.path:获取请求路径
- req.protocol:获取协议类型
- req.query:获取URL的查询参数串
- req.route:获取当前匹配的路由
- req.accepts():检查可接受的请求的文档类型
- req.get():获取指定的HTTP请求头
- req.is():判断请求头Content-Type的MIME类型
-
Response 对象
response 对象表示 HTTP 响应,即在接收到请求时向客户端发送的 HTTP 响应数据
- res.app:同req.app一样
- res.append():追加指定HTTP头
- res.set()在res.append()后将重置之前设置的头
- res.cookie(name,value [,option]):设置Cookie
- res.clearCookie():清除Cookie
- res.download():传送指定路径的文件
- res.get():返回指定的HTTP头
- res.json():传送JSON响应
- res.jsonp():传送JSONP响应
- res.location():只设置响应的Location HTTP头,不设置状态码或者close response
- res.redirect():设置响应的Location HTTP头,并且设置状态码302
- res.render(view,[locals],callback):渲染一个view,同时向callback传递渲染后的字符串,如果在渲染过程中有错误发生next(err)将会被自动调用。callback将会被传入一个可能发生的错误以及渲染后的页面,这样就不会自动输出了。
- res.send():传送HTTP响应
- res.sendFile(path [,options] [,fn]):传送指定路径的文件 -会自动根据文件extension设定Content-Type
- res.set():设置HTTP头,传入object可以一次设置多个头
- res.status():设置HTTP状态码
- res.type():设置Content-Type的MIME类型
静态资源加载
- express.static(path)--中间件
中间件
-
定义
- 中间件是在服务器收到请求和发送响应之前所执行的一些函数 ,它可以访问请求对象, 响应对象
-
功能
- 1.执行任何代码
- 2.修改请求和响应对象
- 3.终结请求-响应循环
- 4.调用堆栈中的下一个中间件
- 5.如果当前中间件没有终结请求-响应循环,则必须调用 next() 方法将控制权交给下一个中间件,否则请求就会挂起。
-
中间件的使用
- app.use([path],中间件函数)
-
分类
-
内置中间件
- express.static()
-
第三方中间件
-
body-parser--转换post请求
- 安装body-parser----npm i body-parser -S
- 引入body-parser----let bodyParser=require('body-parser');
- 使用body-parser----app.use(bodyParser.josn())
- 获取post请求:request.body
-
-
自定义中间件
- 路由
-
路由封装
-
Runter对象:路由中间件,有express.Router()创建
-
步骤
- 1.创建路由文件: use.js
- 2.创建路由对象:let router =express.Roter()
- 3.获取请求:router.get/post/put/delete(path,(req,res)=>{})
- 4.导出路由模块:modules.exports=router
- 5.导出路由模块:let userRouter=requrie("./user)
- 6.将路由中间件绑定路径:app.use(path,userRouter)
模块引擎
-
定义
- 动态渲染页面(可以直接给页面传值,也可以再页面中写循环判断)
-
使用步骤
- 1.安装jade: npm i jade -s
-
- app.set('views','./tpl');//模板引擎存储目录 app.set("view engine','jade');//设置模板引擎
-
- 渲染模板引擎,通过res.render(模板名,{....})
- 4.模板引擎页面:使用传递的值
-
分类
- Pug,Musta,jade
post请求和get请求
-
获取get请求数据
- requset.query
-
获取post请求数据
-
request.body--默认是undefined(未使用中间件前)
-
依赖中间件
-
body-parser --第三方中间件
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended:true})) -
express中间件
app.use(express.json())
app.use(express.urlencoded({extended:true}))
-
-
cookie的使用
-
客户端cookie操作
-
客户端获取cookie
- document.cookie
-
客户端设置cookie
- document.cookie='name=val;max-age=1000'
-
客户端清除cookie
- document.cookie=name=' ';max-age=-1
-
-
服务端cookie操作
-
服务端设置cookie
-
response.cookie(name,val[,options])
res.cookie('name', 'tobi', {'domain':'.example.com', 'path':'/admin', 'secure':true});
res.cookie('remenberme', '1', {'expires':new Date(Date.now() + 90000), 'httpOnly':true});- options是一个对象
- domain String 设置cookie的域名。默认是你本app的域名。
- expires Date cookie的过期时间,GMT格式。如果没有指定或者设置为0,则产生新的cookie。
- httpOnly Boolean 这个cookie只能被web服务器获取的标示。
- maxAge String 是设置过去时间的方便选项,其为过期时间到当前时间的毫秒值。
- path String cookie的路径。默认值是/。
- secure Boolean 标示这个cookie只用被HTTPS协议使用。
- signed Boolean 指示这个cookie应该是签名的。
-
-
服务端获取cookie--依赖cookie-parser中间件 将cookie请求放在请求头部request Header
- 1.app.use(cookieParser());//挂载cookie中间件
-
- req.cookies---服务端获取页面cookie
-
服务端清除cookie
- response.clearCookie()
-
文件上传下载-file控件
-
原理
- 将本地文件保存到服务端的磁盘中文件夹内,然后将服务端文件保存的路径写入到数据库
-
步骤--multer中间件
-
客户端:模板页或html
- .解析form表单里面enctype="multipart/form-data"
- 表单要定义name属性
-
服务端
-
1.安装multer插件:multer实现解析multipart/form-data的数据
-
2.在需要上传文件信息的页面导入multer
-
3.给multer配置参数:multer({dest:“文件上传保存的目录”})
-
4.将multer应用到路由中:
- app.use(multer({dest:'存储到服务端的目录'}).single("表单的name属性值"));-----上传单个文件
- app/router.method({dest:'存储到服务端的目录1'}.array("表单name属性值“),(req,res)=>{....})
-
5.在路由中获取上传文件信息
-
request.file----对应single
-
获取文件信息的属性
- fieldname - 表单提交的文件名(input控件的name属性)
- originalname - 文件在用户设备中的原始名称
- encoding - 文件的编码类型
- mimetype - 文件的Mime类型
- size - 文件的大小
- destination - 文件的保存目录(DiskStorage)
- filename - 文件在destination中的名称(DiskStorage)
- path - 上传文件的全路径(DiskStorage)
-
requset.files----对应array
-
-
6..保存文件:先读(临时文件)后写(保存之后的文件)
-
-
脚手架工具express-generator
-
作用
- 可以快速生成一个基于express框架的应用程序
-
安装脚手架
-
安装包
-
第一种
- npx express-generator(第一种不能使用使用第二种)
- npm install express-generator -g
express
-
第二种
-
-
安装项目依赖
- npm install
-
运行项目
- npm start
-
-
脚手架express-generator搭建项目结构
-
bin目录---可执行文件
- www.js---入口文件
-
node_modules目录---项目依赖包
-
public目录--静态资源文件
- images图片
- JavaScript--js文件
- stylesheet--css文件
-
routes目录--路由
- index.js---首页路由
- user.js---用户路由
-
views目录---模板目录
- error.jade---错误模板
- index.jade---首页模板
- layout.jade---其他模板页的公共部分--模板页模板
-
app.js---express程序初始化文件
-
package.json---项目配置文件
-
-
脚手架设置全局变量
- 1.通过app.set()设置,然后app.get()获取---在路由中通过req/res.app.get()获取
- 2.使用global对象
- 3.将全局变量写入到js文件中导出,然后在需要用到的require导入
XMind: ZEN - Trial Version
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律