NPM: nodejs package manager
官网: www.npmjs.org
命令:
npm -v 查看版本号
npm install moduleName 安装模块到本地
npm install moduleName -g 安装模块到全局
npm install 安装项目时使用
npm init 创建项目时使用
Express框架: 基于NodeJS的,快速、开放、极简的Web开发框架。
下载: npm install express
基本搭建服务器
// 引入express 因为它被放在了node_modules目录下 所以只需要写express即可
var express = require("express");
// 搭建应用
var app = express();
// 监听端口
app.listen(3000);
Express配置路由:
1. 直接app.verbs();
verbs 可以是get 可以是post 可以是http请求类型中的任意一种。
2. 使用路由模块
//获取路由
var route = express.Router();
route.verbs();
app.use(route);
注:verbs的使用方式有两个参数, 第一个是url的pathname匹配路径 第二个是callback
路由的特点:
路由具备拦截功能:当一个对路由匹配了多个函数的时候。
例如:
app.get("/", function(req, res) {})
app.get("/", function() {})
此时如果浏览器发出/http请求,那么只会有第一个函数生效。如果想要让第二个函数也生效那么需要在第一个函数中增加第三个参数,并且在第一个函数内执行next函数
app.get("/", function(req, res, next) {next()})
app.get("/", function() {})
普通express框架node.js服务器
// 引入express 因为它被放在了node_modules目录下 所以只需要写express即可
var express = require("express");
// 引入路由
var route = express.Router();
// 搭建应用
var app = express();
// 搭建路由
route.get("/index.html", function(req, res) {
console.log("访问的是/index.html路由");
})
route.get("/second.html", function(req, res) {
console.log("访问的是/second.html路由");
})
// 让应用程序与路由产生联系
app.use(route);
// 监听端口
app.listen(3000);
静态化
express唯一内置的中间件。
使用方式: app.use(express.static(dirPath));
应用之后,dirPath下的所有文件都可以不配置路由直接访问了。在访问的时候前端url中不要出现dirPath字符串
app.use(express.static(dirpath));
dirpath中的所有文件都可以被访问了。 我们一般将静态文件放在该目录下。
注:在前端访问的时候不要加dirpath这一层。
// 引入express
var express = require("express");
// 搭建应用
var app = express();
// 应用静态化功能
app.use(express.static("./static"));
// 监听端口号
app.listen(3000);
处理get请求
处理get请求主要是获取get请求的数据。
方式: 在路由函数中,直接通过req.query获取数据即可。
// 引入express 因为它被放在了node_modules目录下 所以只需要写express即可
var express = require("express");
// 引入路由
var route = express.Router();
// 搭建应用
var app = express();
// 搭建路由
route.get("/main", function(req, res) {
// 获取get请求的数据
// url.parse(req.url).query 原生中获取query数据的方式
// 在Express中 获取的方式 req.query;
console.log(req.query);
});
// 让应用程序与路由产生联系
app.use(route);
// 监听端口
app.listen(3000);
处理post请求
处理post请求也是主要获取post请求的数据。
方式: 要借助body-parser插件完成。
html代码:
app.js服务器代码:
注:
form表单enctype属性默认是application/x-www-form-urlencoded
处理enctype属性是application/x-www-form-urlencoded表单的时候,
使用 app.use(body_parser.urlencoded({extended: false}));
这句代码作用就是 将 enctype属性是application/x-www-form-urlencoded 表单提交上来的post请求数据解析成对象并挂载在req.body对象身上
// 引入express
var express = require("express");
// 引入body-parser
var body_parser = require("body-parser");
// 定义应用
var app = express();
// 应用body-parser插件
app.use(body_parser.urlencoded({extended: false}));
// 定义路由
var route = express.Router();
// 搭配路由
route.get("/index.html", function(req, res) {
// 这是一个Express给res添加的方法 用于发送页面
res.sendFile(__dirname + "/index.html");
});
// 搭配/login路由
route.post("/login", function(req, res) {
// 从req.body身上获取post提交过来的数据
console.log(req.body);
});
// 挂载路由
app.use(route);
// 监听端口号
app.listen(3000);
上传单个文件
form上传文件
要将form表单的enctype属性 从默认的application/x-www-form-urlencoded 变成 multipart/form-data
要是上传多个文件,必须将设置multiple="true"
处理enctype属性是multipart/form-data表单的时候,使用app.use(body_parser.urlencoded({extended: false})); 无法使用req.body来获取文件数据,所以获取文件数据使用formidable插件来获取数据
formidable文件上传:
前端:
必须在表单中设置enctype属性为 "multipart/form-data"
必须在表单的文件控件中定义name属性值
后端:
在匹配路由中初始化formidable解析对象
var form = new formidable.IncomingForm();
form.uploadDir = "设置文件的上传目录";
form.parse(req, function(err, fields, files) {
err: 表示错误信息对象
fields: 文本域 里面放的是表单中所有input != file的控件信息
files: 文件域 里面放的是每一个上传上来的文件的信息
files.xxx.path: 文件上传上来之后 存放的文件路径
files.xxx.name: 原文件名称
})
html代码:
app.js服务期代码:
// 引入express
var express = require("express");
// 引入fs模块
var fs = require("fs");
// 引入formidable
var formidable = require("formidable");
// 引入路由
var route = express.Router();
// 引入body-parser
var body_parser = require("body-parser");
// 搭建应用
var app = express();
// 配置body-parser
app.use(body_parser.urlencoded({extended: false}));
// 应用静态化功能
app.use(express.static("./static"));
// 匹配上传文件路由
route.post("/upload", function(req, res) {
// 初始化一个表单解析对象
var formid = new formidable.IncomingForm();
// 设置指定目录
formid.uploadDir = "./uploads";
// 解析req
formid.parse(req, function(err, fields, files) {
// 判断是否出错
if(err) {
res.end("出错了");
return;
}
// 获取原文件名称
var oldName = files.upload.path;
// 获取后缀名
var extName = files.upload.name.split(".").pop();
// 定义新文件的名称
var newName = fields.username;
fs.rename(oldName, formid.uploadDir + "/" + newName + "." + extName, function() {
res.end("成功");
})
});
});
// 挂载路由
app.use(route);
// 监听端口号
app.listen(3000);
上传多个文件
要将form表单的enctype属性 从默认的application/x-www-form-urlencoded 变成 multipart/form-data
要是上传多个文件,必须将设置multiple="true"
使用formidable对象的监听file事件
key:上传上来的某一个文件的表单控件的name属性值
value:具体文件对象
注:file事件是formidable对象parse方法 解析出一个file就触发一次file事件,所以必须要写formidable对象parse方法,不能只写file事件
formid.on("file", function(key, value) {
arr.push(value);
})
html代码:
app.js服务器代码:
// 服务器搭建
var express = require("express");
var body_parser = require("body-parser");
var formidable = require("formidable");
var fs = require("fs");
var app = express();
var route = express.Router();
app.use(express.static("./static"));
app.use(body_parser.urlencoded({extended: false})); // 将提交上来的post请求数据解析成body并挂载在req对象身上
// 匹配/login路由
route.post("/upload", function(req, res) {
// 这里的无法使用req.body来获取数据 因为带了文件所以enctype属性变成了multipart/form-data了 要使用formidable来获取数据
// 初始化formid对象
var formid = new formidable.IncomingForm();
formid.uploadDir = "./uploads";
// 定义一个数组
var arr = [];
// 监听file事件
formid.on("file", function(key, value) {
arr.push(value);
})
// 使用该对象解析req对象
formid.parse(req, function(err, fields, files) {
// 在这里将arr中的所有成员全部重命名
for(var i = 0; i < arr.length; i++) {
var oldPath = arr[i].path;
var newPath = formid.uploadDir + "/" + arr[i].name;
fs.renameSync(oldPath, newPath)
}
res.end("成功");
})
});
// 挂载路由
app.use(route);
app.listen(3000);
form表单post的body-parser问题
var express = require("express");
var route = express.Router();
//post请求 引入body_parser模块
var body_parser = require("body-parser");
var app = express();
app.use(express.static("./static"));
//处理enctype属性是application/x-www-form-urlencoded表单的时候用这个
//将 enctype属性是application/x-www-form-urlencoded 表单提交上来的post请求数据解析成对象并挂载在req.body对象身上
app.use(body_parser.urlencoded({extended: false}));
route.post("/login", function (req, res) {
console.log(req.body);
})
//上传文件的时候 要将form表单的enctype属性 从默认的application/x-www-form-urlencoded 变成 multipart/form-data
//处理enctype属性是multipart/form-data表单的时候
//无法使用req.body来获取数据 使用formidable来获取数据
app.use(route);
app.listen(3000);
Express模板
Express能够使用的模板有: jade、 ejs
文件的后缀名分别是 index.jade 和 index.ejs
Express默认使用的是jade 因为jade的语法与之前接受的语法不一样。 所以我们采用ejs模板。
ejs模板
语法: <%%> 负责开辟一个JS环境
<%=%> 负责将=后的内容输出在页面中 =必须在<%右侧紧邻
渲染模板:
所有模板文件默认情况下必须放在根目录下的views文件夹中后缀名是.ejs
使用res.render(templateFilePath, dictionary)
templateFilePath: 它的写法是相对路径写法 从views后开始书写
dictionary: 渲染模板文件所需的字典对象
需要下载ejs模板
npm install ejs
在使用的时候不必引入该模块。
默认情况下要新建一个views文件夹,并将所有的ejs文件放在该文件夹下。直接在路由处理函数中使用
res.render(path, dictionary);
path: 在views目录中的路径
dictionary: 字典
// 引入express
var express = require("express");
// 引入路由
var route = express.Router();
// 引入body-parser
var body_parser = require("body-parser");
// 搭建应用
var app = express();
// 配置body-parser
app.use(body_parser.urlencoded({extended: false}));
// 应用静态化功能
app.use(express.static("./static"));
// 处理/login路由
route.post("/login", function(req, res) {
// 获取提交的数据
var username = req.body.username;
// 渲染模板 生成html 返回给前端
res.render("main.ejs", {
username: username
})
})
// 挂载路由
app.use(route);
// 监听端口号
app.listen(3000);
cookie
后端设置cookie
res.cookie(key, value, options);
key: 名称
value: 值
options: 配置对象(可选)
maxAge: 最大生效时间 毫秒值书写形式
httpOnly: 只能够在服务器端访问cookie 值是布尔值
domain: 主域
path: cookie可以被携带的路径 默认是/ (也就是发出http请求的时候所有路径都带cookie 如果是 /aaa/ 那么只会在/aaa/index.html /aaa/second.html /aaa/css.css 时才会带上该cookie)
expires: 过期日期 与maxAge一样作用 书写形式是日期
后端获取解析cookie
要借助cookie-parser插件
cookie-parser插件作用: 解析前端提交上来的cookie数据,并组成一个对象挂载在req对象身上
使用方式:
var cookie_parser = require("cookie-parser");
app.use(cookie_parser());
var username = req.cookie.username;
app.js服务器代码:
// 搭建服务器
var express = require("express");
var body_parser = require("body-parser");
// 引入cookie-parser模块
var cookie_parser = require("cookie-parser");
var route = express.Router();
var app = express();
app.use(cookie_parser()); // 将前端的提交上来的cookie请求头 解析成cookies对象 挂载在req身上
var arr = [
{
username: "王老五",
password: "12345"
},
{
username: "张三",
password: "12345"
}
]
app.use(body_parser.urlencoded({extended: false}));
app.use(express.static("./static"));
route.post("/login", function(req, res) {
// 获取前端提交过来的数据
var username = req.body.username;
var password = req.body.password;
// 拿着数据与arr中的数据循环比较
for(var i = 0; i < arr.length; i++) {
if(username === arr[i].username && password === arr[i].password) {
// 说明登录成功
// 要保持状态 所以要设置cookie
res.cookie("username", username, {
maxAge: 1000 * 3600,
httpOnly: false
});
// 跳转
res.redirect("/main");
return;
}
}
});
route.get("/clear", function(req, res) {
res.clearCookie("username");
res.end("aaa");
});
route.get("/main", function(req, res) {
console.log(req.cookies);
// 获取cookie
var username = req.cookies.username;
if(!username) {
res.redirect("/index.html");
return;
}
// 渲染一个模板给前端
res.render("main.ejs", {
username: username
})
})
app.use(route);
app.listen(3000);
session
会话: 浏览器打开,访问一个服务器,一个会话诞生,关闭浏览器,会话结束。
cookie的服务器版本。
cookie存储在浏览器端,存储数据。
session就是服务器端的存储用户数据的一个东西。
session也是用于保持登录状态的。
cookie将数据存储在浏览器端,不安全。所以在服务器端设置了session。
运行机制: 当浏览器提交登录请求到达服务器之后,服务器经过验证,并不直接把用户名和密码放到cookie中返回给前端,而是将用户名和密码放在session中,并让session生成一个随机字符串。session能够知道随机字符串与用户名密码的对应关系。服务器将这个随机字符串设置到session中并返回给前端。 前端中的cookie存储的就不是直接的用户信息。而是“间接”的用户信息。该信息只对服务器有用。之后每一次浏览器发出请求,都会将这个随机字符串带到服务器。服务器就知道登录的用户是谁。
express-session模块
下载:
npm install express-session
使用方式:
app.use(session({
secret: "dsjfaoiaehfoiewhfoiehafoiewhfoihewaoifh",
resave: false,
saveUninitialized: false
}))
此后可以在任意路由下,通过req.session.xxx 读取 或设置信息。
生成的随机码:
app.js服务器代码:
var express = require("express");
var session = require("express-session");
var body_parser = require("body-parser");
var app = express();
app.use(express.static("./static"));
app.use(body_parser.urlencoded({extended: false}));
app.use(session({
secret: "dsjfaoiaehfoiewhfoiehafoiewhfoihewaoifh",
resave: false,
saveUninitialized: false
}))
var route = express.Router();
var arr = [
{
username: "王老五",
password: "12345"
},
{
username: "张三",
password: "12345"
}
];
route.post("/login", function(req, res) {
// 登录请求来了
var username = req.body.username;
var password = req.body.password;
// 循环比较
for(var i = 0; i < arr.length; i++) {
if(username === arr[i].username && password === arr[i].password) {
// 登录成功
req.session.username = username;
req.session.password = password;
// 跳转路径
res.redirect("/main");
}
}
})
// 匹配/main路由
route.get("/main", function(req, res) {
var username = req.session.username;
// 判断是否登录过
if(!username) {
// 登录去
res.redirect("/index.html");
return;
}
// 给前端渲染一个页面
res.render("main.ejs", {
username: username
});
})
app.use(route);
app.listen(3000);