express项目搭建 初始化详细步骤

案例

一、对每一个POST请求都设置CSRF防护

实际上,不仅仅转账需要CSRF防护,每一个post请求都需要做csrf的防护措施。

webA项目中的app.js:

const router = express.Router();router.all("/register",(res,req)=>{....
})function csrfProtect(req, res, next){let method = req.methodif(method=="GET"){let csrf_token = getRandomString(48);res.cookie('csrf_token', csrf_token);next() //执行跳转到下一个函数执行,即app.use(beforeReq,router)中的下一个}else if(method=="POST"){// 判断响应头中的x-csrftoken值,和cookies中的csrf_token进行对比console.log(req.headers["x-csrftoken"]);console.log(req.cookies["csrf_token"]);if((req.headers["x-csrftoken"] === req.cookies["csrf_token"])){console.log("csrf验证通过!");next()}else{res.send("csrf验证不通过!!");return}}
}app.use(csrfProtect,router)

项目

一、项目从初始化

1、新建项目文件夹News

2、初始化项目 yarn init -y 或者 npm init -y

3、安装express,yarn add express 或者 npm install express

4、其次在 News 目录中,创建一个名为 app.js 的文件
在这里插入图片描述

const express = require("express");
const app = express();app.get("/",(req, res)=>{res.send("hello News");
})app.listen(3000, ()=>{console.log('Example app listening on port 3000!');
})

浏览器中访问http://localhost:3000/ , 看到hello News,则项目初始化成功;

二、静态资源和模板引擎的设置

2.1、设置静态资源

app.js中添加下面代码设置静态资源的访问路径:

app.use(express.static("public")); 

在这里插入图片描述

2.2、设置模板引擎

项目采用的是art-templates模板引擎,使用之前需要安装 art-template 和 express-art-template

yarn add art-template   或者   npm install art-template
yarn add express-art-template  或者  npm install express-art-template

我们模板引擎的目录为 /views

const path = require('path');// 1、修改模板引擎为html,导入express-art-template
app.engine('html', require('express-art-template'));
// 2、设置运行的模式为开发模式
app.set('view options', {debug: process.env.NODE_ENV !== 'development'
});
// 3、设置模板存放目录为views文件夹
app.set('views', path.join(__dirname, 'views'));
// 4、设置引擎后缀为html
app.set('view engine', 'html');app.get("/",(req, res)=>{res.render("news/index");
})

注意:
静态资源文件中的路径需要使用绝对路径,例如:/news/css/base.css
在这里插入图片描述

(VScode 快捷键提示Ctrl+shift+L: 选中某字符串后,批量选择本页面中出现的所有该字符串,之后就可以批量修改了)

三、项目中设置post请求方式的处理

获取post请求体参数的时候使用body-parser模块;

添加以下设置代码:

// 1、引入body-parser
const bodyParser = require('body-parser');// 2、bodyParser功能添加到项目app中
app.use(bodyParser.urlencoded({ extended: false }));// parse application/x-www-form-urlencoded   针对普通页面提交功能
app.use(bodyParser.json());  // parse application/json    针对异步提交ajax

之后在路有接口中就可以通过req.body获取请求体参数了。

四、添加cookie和session的配置

先安装cookie-parser和cookie-session :

yarn add cookie-parser 或者 npm install cookie-parser --save
yarn add cookie-session 或者 npm install cookie-session  --save

app.js中添加设置:

const cookieParser = require('cookie-parser');
const cookieSession = require('cookie-session');// cookie的注册
app.use(cookieParser());  
// session的注册
app.use(cookieSession({name:"my_session",keys:["%$#^&^%&TSFR#$TRGDRG$%GFDG%^$#%#^GFDGRDHG$#@^Y%"],maxAge:1000*60*60*24*2    //过期时间设置为2天
}));

后面就可以通过
req.session[属性名] = 值来设置session, req.cookies["属性名"]取值
res.cookie("属性名","值")来设置cookie, req.session["属性名"]取值
在这里插入图片描述

在这里插入图片描述
app.js完整代码:

const express = require('express');
const path = require('path')
const cookieParser = require('cookie-parser')
const cookieSession = require('cookie-session')// bodyParser用来处理post请求
const bodyParser = require('body-parser')const app = express()// 获取post请求参数的配置
// parser application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parser application/json  针对异步提交ajax
app.use(bodyParser.json())// 注册cookie 和 session
app.use(cookieParser())
app.use(cookieSession({name: 'my_session',keys: ["sadafdkjaoisdj(*)@#!@klajkl@#%$#deafda"],maxAge:  1000*60*60*24*2 //设置过期时间,两天后过期
}))// 关于静态资源的文件夹的指定
app.use(express.static("public"))// 关于模板的配置
// 1. 修改模板引擎为html,导入express-art-template
app.engine('html', require('express-art-template'))
// 2. 设置运行的模式为开发模式
app.set('view options', {debug: process.env.NODE_ENV !== 'development'
});
// 3. 设置模板存放目录为views文件夹
app.set('views', path.join(__dirname, 'views'))
// 4. 设置引擎后缀为html
app.set('view engine', 'html')app.get('/', (req, res)=> {// 测试设置cookie和sessionres.cookie("name","nodejs")req.session["age"] = 21res.render('news/index.html')
})app.get('/get_cookie', (req, res)=> {// 测试获取cookieres.send('cookie中 name的值为:' + req.cookies["name"])
})app.get('/get_session', (req, res)=> {// 测试获取sessionres.send('session中 my_session中age的值为:' + req.session["age"])
})app.listen(3001, (err)=> {if(err) {console.log(err)return;}console.log('服务器已经启动,端口为:3001')
})

五、抽取app.js中的配置信息

目前,app.js已经越写越多了, 我们要把这个文件中的配置信息全部抽取出来作为一个独立的配置文件

项目目录下新建配置文件config.js

const express = require("express");
const path = require("path");
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const cookieSession = require('cookie-session');var appConfig = app => {// 静态资源找寻的文件夹app.use(express.static("public")); // 模板引擎app.engine('html', require('express-art-template'));app.set('view options', {debug: process.env.NODE_ENV !== 'development'});app.set('views', path.join(__dirname, 'views'));app.set('view engine', 'html');// 设置获取请求体app.use(bodyParser.urlencoded({ extended: false }));app.use(bodyParser.json()); // cookie的注册app.use(cookieParser());  // session的注册app.use(cookieSession({name:"my_session",keys:["%$#^&^%&TSFR#$TRGDRG$%GFDG%^$#%#^GFDGRDHG$#@^Y%"],maxAge:1000*60*60*24*2    //过期时间设置为2天}));
}module.exports = appConfig;
const express = require('express');
const path = require('path')
const cookieParser = require('cookie-parser')
const cookieSession = require('cookie-session')
// bodyParser用来处理post请求
const bodyParser = require('body-parser');let appConfig = (app) => {// 获取post请求参数的配置// parser application/x-www-form-urlencodedapp.use(bodyParser.urlencoded({ extended: false }))// parser application/json  针对异步提交ajaxapp.use(bodyParser.json())// 注册cookie 和 sessionapp.use(cookieParser())app.use(cookieSession({name: 'my_session',keys: ["sadafdkjaoisdj(*)@#!@klajkl@#%$#deafda"],maxAge: 1000 * 60 * 60 * 24 * 2 //设置过期时间,两天后过期}))// 关于静态资源的文件夹的指定app.use(express.static("public"))// 关于模板的配置// 1. 修改模板引擎为html,导入express-art-templateapp.engine('html', require('express-art-template'))// 2. 设置运行的模式为开发模式app.set('view options', {debug: process.env.NODE_ENV !== 'development'});// 3. 设置模板存放目录为views文件夹app.set('views', path.join(__dirname, 'views'))// 4. 设置引擎后缀为htmlapp.set('view engine', 'html')
}module.exports = appConfig

app.js中:

// 引入配置文件
const config = require("./config");// 创建应用程序对象
const app = express();// 执行配置信息
config(app);
const express = require('express');
const AppConfig = require("./config.js")const app = express()
// new AppConfig(app)
AppConfig(app)app.get('/', (req, res)=> {// 测试设置cookie和sessionres.cookie("name","nodejs")req.session["age"] = 21res.render('news/index.html')
})app.get('/get_cookie', (req, res)=> {// 测试获取cookieres.send('cookie中 name的值为:' + req.cookies["name"])
})app.get('/get_session', (req, res)=> {// 测试获取sessionres.send('session中 my_session中age的值为:' + req.session["age"])
})app.listen(3001, (err)=> {if(err) {console.log(err)return;}console.log('服务器已经启动,端口为:3001')
})

站在更高的角度,用面向对象的方式去写:

class AppConfig{constructor(app){this.app = appthis.app.use(express.static("public"));this.app.engine('html', require('express-art-template'));this.app.set('view options', {debug: process.env.NODE_ENV !== 'development'});this.app.set('views', path.join(__dirname, 'views'));this.app.set('view engine', 'html');this.app.use(bodyParser.urlencoded({ extended: false }));this.app.use(bodyParser.json()); this.app.use(cookieParser());this.app.use(cookieSession({name:"my_session",keys: ["FGFDG#$%%YDFGSDHDRY$@#%$&^%*^%%%$^RFDGFJGRSA"],maxAge: 1000 * 60 *60 *24 * 2}));    }
}//调用的时候:
let config = new Config(app)
const express = require('express');
const path = require('path')
const cookieParser = require('cookie-parser')
const cookieSession = require('cookie-session')
// bodyParser用来处理post请求
const bodyParser = require('body-parser');class AppConfig {// 看成创建对象的时候执行的代码constructor(app) {this.app = app// 获取post请求参数的配置// parser application/x-www-form-urlencodedthis.app.use(bodyParser.urlencoded({ extended: false }))// parser application/json  针对异步提交ajaxthis.app.use(bodyParser.json())// 注册cookie 和 sessionthis.app.use(cookieParser())this.app.use(cookieSession({name: 'my_session',keys: ["sadafdkjaoisdj(*)@#!@klajkl@#%$#deafda"],maxAge: 1000 * 60 * 60 * 24 * 2 //设置过期时间,两天后过期}))// 关于静态资源的文件夹的指定this.app.use(express.static("public"))// 关于模板的配置// 1. 修改模板引擎为html,导入express-art-templatethis.app.engine('html', require('express-art-template'))// 2. 设置运行的模式为开发模式this.app.set('view options', {debug: process.env.NODE_ENV !== 'development'});// 3. 设置模板存放目录为views文件夹this.app.set('views', path.join(__dirname, 'views'))// 4. 设置引擎后缀为htmlthis.app.set('view engine', 'html')}
}
module.exports = AppConfig

在这里插入图片描述

六、抽取app.js中的路由接口函数

项目文件夹下新建routes文件夹,新建index.js:

const express = require('express');
const router = express.Router();router.get('/', (req, res) => {//返回这个页面res.render('news/index');
});
module.exports = router

在这里插入图片描述

config.js中添加路由的设置

const indexRouters = require('./routes/index');
var appConfig = app => {...// 路由的设置app.use(indexRouters);  //首页相关路由接口
}

在这里插入图片描述
app.js:

const express = require('express');
const AppConfig = require("./config.js")const app = express()
let appConfig = new AppConfig(app) // 以对象的方式进行调用app.listen(appConfig.listenPort, (err)=> {if(err) {console.log(err)return;}console.log(`服务器已经启动,端口为:${appConfig.listenPort}`)
})

在这里插入图片描述

七、项目数据表分析(见分析图)

八、添加数据库配置

8.1、先创建数据库,并导入数据

把数据库导入数据有两种方式

方式一:使用带界面的Navicat

在这里插入图片描述

在这里插入图片描述

稍等5到10分钟,等待数据导入成功

方式二:也可以直接在cmd窗口中通过连接数据库创建数据库后导入数据

先创建数据库

mysql -uroot -pcreate database news charset=utf8;use news;source  G:\news.sql;    

(注意:该目录不能出现中文!!!)

同样稍等5到10分钟,等待数据导入成功

8.2、项目中测试数据库

先安装mysql:

yarn add mysql 或者npm install mysql

把今天资料中提供的db文件夹放置到项目目录下,

测试数据库的使用,查询新闻分类表并相应回页面:

const handleDb = require("../../db/handleDb");router.get("/",(req, res)=>{(async function index(){let result = await handleDb(res,"info_category", "find", "info_category数据库查询出错");res.send(result);})();
})

九、初步获取图片验证码

先安装验证码获取的模块 ,在项目目录下:

yarn add svg-captcha

使用说明:

let captchaObj = new Captcha(); // 创建对象
let captcha = captchaObj.getCode(); // 调用获取验证码的方法captcha.text  //就是验证码文本
captcha.data  //就是验证码图片内容
//注意:返回给浏览器的时候,需要设置响应头
res.setHeader('Content-Type', 'image/svg+xml');

具体实现

项目目录下,新建utils文件夹,复制captcha文件夹到utils下。

routes下新建验证模块 passport.js:

const express = require('express');
const Captcha = require('../utils/captcha');  // 引入captcha工具const router = express.Router();router.get('/password/image_code', (req, res) => {let captchaObj = new Captcha();  // 创建对象let captcha = captchaObj.getCode();  // 调用获取验证码的方法console.log("获取验证码的接口");console.log(captcha.text);   // 验证码文本//配合img标签的src属性请求来展示验证码图片的时候,需要设置响应头res.setHeader('Content-Type', 'image/svg+xml');  res.send(captcha.data);   // 响应验证码图片到浏览器
});module.exports = router

config.js中注册,把passwordRouters注册到app上

const passwordRouters = require('./routes/password');var appConfig = app => {...// 路由的设置app.use(indexRouters);  //首页相关路由接口app.use(passwordRouters);  //验证相关路由接口(登录、注册、获取验证码等)
}

在浏览器中请求:http://localhost:3000/password/image_code

十、注册流程分析(见注册流程分析图)

十一、完整验证码获取流程

/*1、生成验证码2、将验证码文本存入session   (后面点击注册按钮的时候,注册接口中需要重新获取这个验证码文本和用户输入的验证码进行对比)3、发送验证码数据
*/// 1、生成验证码
let captchaObj = new Captcha();  // 创建对象
let captcha = captchaObj.getCode();  // 调用获取验证码的方法
// 2、将验证码文本存入session   
req.session["IMG_CODE"] = captcha.text;
console.log(req.session)
// 3、发送验证码数据
res.setHeader('Content-Type', 'image/svg+xml');  //设置响应头
res.send(captcha.data);   // 响应验证码图片到浏览器

十二、解决点击获取验证码图片问题

/public/news/js/main.js中,加上一个随机数:

// 1.设置图片url地址
image_url = '/passport/image_code/'+Math.random()

passport.js接口中:

router.get("/passport/image_code/:float",  ...

的方法
// 2、将验证码文本存入session
req.session[“IMG_CODE”] = captcha.text;
console.log(req.session)
// 3、发送验证码数据
res.setHeader(‘Content-Type’, ‘image/svg+xml’); //设置响应头
res.send(captcha.data); // 响应验证码图片到浏览器


## 十二、解决点击获取验证码图片问题/public/news/js/main.js中,加上一个随机数:```js
// 1.设置图片url地址
image_url = '/passport/image_code/'+Math.random()

passport.js接口中:

router.get("/passport/image_code/:float",  ...

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470631.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Chapter7-4_來自獵人暗黑大陸的模型 GPT-3

文章目录1 为何来自暗黑大陆2 GPT-3的野心3 GPT-3的效果4 Beyond GPT-3本文为李弘毅老师【來自獵人暗黑大陸的模型 GPT-3】的课程笔记,课程视频youtube地址,点这里👈(需翻墙)。 下文中用到的图片均来自于李宏毅老师的PPT,若有侵权…

二、PHP框架Laravel学习笔记——路由的定义和控制器

一.路由的定义 什么是路由?路由就是提供接受 HTTP 请求的路径,并和程序交互的功能; 简单点理解,就是为了提供访问程序的 URL 地址,所做的一些设置工作; phpstorm 支持 cmd 操作,左…

Chapter7-5_Multilingual BERT

文章目录1 什么是Multilingual BERT2 Zero-shot Reading Comprehension3 Cross-lingual Alignment4 How alignment happens本文为李弘毅老师【Multilingual BERT】的课程笔记,课程视频youtube地址,点这里👈(需翻墙)。 下文中用到的图片均来自…

deepin tim(wine)无法安装_浅析国产操作系统深度deepin

经过两天的努力,终于实现了win10下跟deepin 的双系统,经过我实际操作,发现win7环境下装双系统还是有问题的。虽然deepin系统也能安装成功,但是win系统却是无法顺利启动,一直卡在系统初始界面无限循环。而更换win10之后…

三、PHP框架Laravel学习笔记——路由参数、重定向、视图

一.路由参数 我们已经学习了部分路由参数的功能,比如动态传递{id};那么,有时这个参数需要进行约束,我们可以使用正则来限定必须是数字; Route::get(task/read/{id}, TaskControllerread) ->where(id, …

Chapter7-6_Text Style Transfer

文章目录1 什么是Text Style Transfer2 Cycle GAN2.1 Gumbel-softmax2.2 Continuous Input for Discriminator2.3 Reinforcement Learning2.4 效果3 Star GAN4 Feature Disentangle5 Unsupervised Abstractive Summarization6 Unsupervised Translation7 Unsupervised Speech R…

Student学生管理系统

1.定义各个层 2.添加各个层之间的引用 DAL 层调用Model BLL层调用DAL和Model UI层调用BLL和Model层 Model层供各个层调用 3.根据数据库建立实体类,每张表对应一个实体类 4.在DAL层调用MyTool类和SQLhelper类,添加system.Configuration 引用 并编写app.config 在SqlHelper类调用…

一、PHP框架Laravel——入门和安装

一.版本化方案 Laravel 框架是一款简洁、优秀且优雅的 PHP 开发框架;Laravel 到底怎么读,由于不是真实的单词,导致争论较多目前已知:[lrəvel][lɑːrəvel][lɑːrvl]有这几种;Laravel 从 6.x 开始进入到…

iscsi没有可用于使用快速连接登陆的目标_【解密】5G商用在即 OPPO快速网络切换方法;高管宣布华为河图商标注册成功;小米折叠屏专利曝光 类似于摩托罗拉Razr...

1.【专利解密】5G商用在即 OPPO快速网络切换方法2.好消息!高管宣布华为河图商标注册成功3.小米折叠屏专利曝光 类似于摩托罗拉Razr4.索尼Xperia提交新专利 上下双升降结构1.【专利解密】5G商用在即 OPPO快速网络切换方法【嘉德点评】OPPO发明的网络切换专利&#xf…

搞懂DEtection TRanformer(DETR)

文章目录1 bipartite matching loss2 模型总体框架2.1 backbone2.2 transformer2.2.1 encoder2.2.2 decoder2.2.3 prediction heads3 模型效果参考文献本文描述了笔者在阅读了一些文献之后,对 End-to-end Object Detection with Transformers(DETR) 的理解。DETR是一…

四、PHP框架Laravel学习笔记——路由命名和分组

一.路由命名 给一个制定好的路由进行命名,可以生成 URL 地址或进行重定向; Route::get(task, TaskControllerindex)->name(task.index); 在控制器区域,使用助手函数 route()来获取路由生成的 URL 地址; //生成 ur…

echart 数据点可以加链接吗_地理可视化就这么简单、酷炫,蚂蚁金服AntV 空间数据可视化引擎 L72.0发布...

导读L7 是由蚂蚁金服 AntV 数据可视化团队推出的基于 WebGL 的开源大规模地理空间数据可视分析开发框架。L7 中的 L 代表 Location,7 代表世界七大洲,寓意能为全球位置数据提供可视分析的能力。L7 以图形符号学为理论基础,将抽象复杂的空间数…

论文阅读 - Large-scale weakly-supervised pre-training for video action recognition

文章目录1 概述2 数据的收集方式3 使用的模型4 预训练时的一系列问题4.1 预训练的数据是不是越多越好?4.2 用于预训练的模型是不是越大越好?4.3 预训练数据的标签种类和数量是不是越多越好?4.4 用于预训练的每个video有长有短,时长…

excel记账本模板_原来这才是老板最喜欢看的财务报表!这些模板送你,录入自动生成...

【原来这才是老板最喜欢看的财务报表!这些模板送你,录入自动生成】都说财务报表做好,会计下班会很早!财务报表做的妙,升职加薪少不了!会计每到下班拖后腿的就是要整理好各种报表然后发给领导,会…

五、PHP框架Laravel学习笔记——回退、当前路由、单行为

一.单行为控制器 之前的课程,我们简单的创建和定义了控制器,并继承了控制器基类;为何要继承基类?因为继承基类后,可以使用基类的方法,比如中间件等;继承基类后除了支持中间件快捷使…

Chapter7-7_Deep Learning for Coreference Resolution

文章目录1 什么是coreference resolution2 框架2.1 Mention Detection2.2 Mention Pair Detection2.3 End-to-End2.4 Span Representation2.5 Pratical Implementation2.6 Result3 应用本文为李弘毅老师【Deep Learning for Coreference Resolution】的课程笔记,课程…

pwn和逆向的区别_Pwn之简单patch

亲爱的,关注我吧9/27文章共计1389个词图片xue微有点多注意流量哦预计阅读7分钟来和我一起阅读吧1引言在攻防的时候不仅仅需要break,还需要fix将漏洞patch上。2工具 这里我使用的是keypatch这个ida脚本下载地址:https://github.com/keystone-engine/keypatch/blob/ma…

python n个list如何组成矩阵_通过学习在processing中操作图片,掌握python 列表操作...

这次的教学非常简单,只需要安装了python模式的processing就可以(安装教程见专栏目录)。我从网上找了一个比100*100稍微大一点的图片,你可以也找一个。然后我们就可以一起开始今天的学习啦~(请先阅读本专栏中的processi…

六、PHP框架Laravel学习笔记——响应设置和重定向

一.响应设置 路由和控制器处理完业务都会返回一个发送到浏览器的响应:return;比如字符串会直接输出,而数组则会输出 json 格式,本身是 Response 对象; return [1, 2, 3]; //输出 json 格式 return respo…

论文阅读 - TransNet and TransNet V2

文章目录1 概述2 模型结构简述2.1 TransNet2.2 TransNet V23 数据集的构建4 模型效果5 参考文献1 概述 有些时候,一段视频是由多段短视频拼接而成的。拼接可以是直接拼接(硬拼接,见图2),也可以是由一个转场过渡拼接&a…