express
包文件引入
const express = require('express');
启动服务器
const app = express();
...
app.listen(8050, ()=>{
console.log('8050端口已启动!');
});
定义静态资源服务器
const path = require('path');
// 定义静态资源服务器
// 指定./resource目录作为存储静态资源文件的目录
app.use(express.static(path.join(dirname, './resource')));
数据预处理工具
// 解析JSON格式的数据并添加到req.body中
app.use(express.json());
// 解析表单中url-encoded格式的数据
app.use(express.urlencoded({extended:false}));
当index.html文件不在静态资源服务器的目录下,如何获取?
const fs = require('fs');
...
app.get('/', (req, res)=>{
fs.readFile('./index.html', 'utf-8', (err, data)=>{
if (err) throw err;
res.send(data);
});
});
或者
/*
返回文件,不需要通过fs模块读取文件哦!
res.sendFile(string path)
*/
设置响应头(包含cookie)
app.get('/api/vi/data', (req, res)=>{
// 第一次发起请求时,打印的应该是null,之后的每次打印都会打印cookie的值
console.log(req.headers,cookie);
let data = [1, 2, 3];
// 设置响应头
/*
set() 和 append()区别
res.set({author:"ami"});
res.set({author:"ami1"});出现相同字段是后面会覆盖前面的
res.append("author":"ami") 追加,不会覆盖
*/
res.set({
author: 'Ami',
age: 16,
// 设置cookie(token值:免登录的通关令牌)
'Set-Cookie': 'session=11531',
});
res.send(JSON.stringify(data));
});
中间件
中间处理程序,即先进行业务处理,再返回处理后的结果。
// 默认 1次http服务中,只能发送1次响应报文,多次发送会报错
app.get(
'/',
(req, res, next) => {
console.log('1');
// 立刻调用下一个回调函数。直至最后一个
next();
},
(req, res, next) => {
console.log('2');
next();
console.log('4'); // 最后执行 ==> 因为next()函数是立即调用下一个函数,故暂时跳过其后面的代码
},
(req, res) => {
console.log('5');
res.send('end');
}
);
路由
// 某一业务处理中,存在多个子路由
// 创建shop小应用 ./router/shop.js
const express = require('express');
let shop = express();
shop.get('/cart', (req, res) => {
console.log(req.url); //获取当前服务中监听的路由(第一个参数/子路由)
console.log(req.baseUrl); //获取当前服务器中路由实例所挂载的url/路由
console.log(req.path); //返回的是请求url地址中的路由部分 和req.url基本一致
// 获取协议 http https(更安全)
console.log(req.protocol);
res.send('cart');
});
shop.get('/price', (req, res) => {
console.log(req.url);
res.send('price');
});
shop.get('/sum', (req, res) => {
console.log(req.url);
res.send('sum');
});
// 暴露变量的两种方式
// module.exports = { shop }; // 因为exports是一个对象呢!
exports.shop = shop;
// 将shop应用挂载到app应用上面 ./index.js
const { shop } = require('./router/shop');
app.use('/shop', shop);
// 把单个路由应用挂载到多个地址上面!!!
// app.use(['/shop', '/shop1', '/shop2'], shop);
批量预处理
app
.route('/shop/cart')
.all((req,res,next)=>{
// 在请求进到任意的监听处理中之前,先统一进行预处理
next();
})
.options((req, res) => {})
.post((req, res) => {});
路由匹配规则
防止因为路由写错导致请求失败的问题
? => 0/1
* => 任意长度的字符,(如果不生效,加\转义)
+ => 至少1个前面的字符
()? => 表示()包含的一组字符可以要,也可以不要
:num => 动态路由参数num => 通过req.params调用 => page:num => page2,注意冒号不需要写的!!!!!!!!!!!
app.use('/api/v2/data?', (req, res) => {
res.send('use');
});
cookie
var cookieParser = require('cookie-parser');
app.use(cookieParser());
// 设置cookie
res.cookie("name","11")
res.set({Set-Cookie:"name=11"})
// 获取cookie
req.cookies
设置HTTP响应状态码
/*
设置HTTP响应状态码
- 信息响应(100-199)
- 成功响应(200-299)
- 重定向消息(300-399)
- 客户端错误响应(400-499)
- 服务端错误响应(500-599)
res.status()
*/
重定向
/*
重定向!!!!!!!!!!
==> 需要注意的是:一旦进行了重定向后,就没有必要再res.send()了,直接在新页面进行处理,然后在相应数据。
==> res.redirect("www.baidu.com")
*/
下载文件的两种方式
/*
下载文件
- res.attachment() ==> 会在响应报文中看到:Content-Disposition: attachment; filename="1.jpg"
app.get('/api/v1/data', (req, res) => {
fs.readFile('./resource/images/img.PNG', 'utf-8', (err, data) => {
if (err) throw err;
res.attachment('1.jpg');
res.send(data);
});
});
- res.download() ==> 个人感觉它是对attachment()和readFile()的一个封装
*/
app.get('/api/v1/data', (req, res) => {
res.download(
path.join(__dirname, './resource/images/img.PNG'),
'1.jpg',
(err) => {
if (err) {
throw err;
}
}
);
});