node文件上传+cookie+ejs +脚手架

项目开发流程

后端。

把前端给的文件一一归类。

1、html页面放在views文件夹,并且要为每一个html页面设计一个路由

2、静态资源放在static或public

3、配置一些post中间件(因为要接收post传递过来的参数)

4、配置开放静态资源的中间件.

文件上传 (formidable)

把用户本地的文件上传到服务器上。

前端

必须是post,不写enctype 属性会默认enctype=application/x-www-form-urlencoded 在发送时编码所有字符。而设置enctype=“multipart/form-data” 不对字符编码。因此req.body不能用。

<form action="/注册地址" enctype="multipart/form-data" method="post">
	<input name="username" placeholder="用户名"><hr>
	<input type="file" name="f"><hr>
	<button>注册</button>
</form>

后端

  • 使用formidable第三方包(中间件)接收文件和数据。
npm install formidable
  • formidable包(中间件)使用:
const formidable = require('formidable');
app.post('/upload',(req,res)=>{
//实例化接收文件数据的表单实例
const form = formidable({
       uploadDir:'uploads',//上传的临时路径
})
//form.parse才是接收数据的方法,它是回调函数风格.
form.parse( req,(err,fields,files)=>{
//fields: 普通的表单数据 即除type="file"以外的数据 比如用户名、密码、性别... 
//files: 文件数据 对象 { f: {size: 37186, path: '',name: 'erha1.jpg',type: 'image/jpeg' }}
    });
});

应用:

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

app.post('/upload',(req,res)=>{

    //实例化接收文件数据的表单实例
    const form = formidable({
       uploadDir:'uploads',//接收上传文件的路径,相对于当前cmd打开的路径。
        //uploadDir:'/uploads',//要么不写路径,要么写绝对路径。如这里写路径则从c盘找。
    })

//form.parse才是接收数据的方法,它是回调函数风格.
    form.parse( req,(err,fields,files)=>{
//fields : 普通的表单数据 比如用户名、密码、性别... 除type="file"以外的数据
//files: 文件数据 对象 { f1: {size: 37186, path: '',name: 'erha1.jpg',type: 'image/jpeg' }}

        let timeStamp = require('time-stamp')
        let name = files.f1.name
        let suffixName = path.extname( name ) //得到了后缀名.       
        let t = timeStamp('YYYYMMDDHHmmss')
        let random = (Math.random() + '').substring(2,8)


            //原路径
            let oldpath = files.f1.path
            //let newpath = 'uploads/' + files.f1.name  //保留原文件名的文件上传
            //新文件名
            let newpath = 'uploads/' + t + ran + suffixName 
             //将文件传到upload路径
            fs.renameSync( oldpath,newpath )

        res.send('文件上传')
    } )

   
})

服务器处理完毕响应结果

  • 保留原文件名

  • 生成及其他文件名

​ 1)年月日时分秒 + 8位随机数

​ 2)使用第三方模块uuid,使用方法:https://www.npmjs.com/package/uuid。

cookie

介绍

Cookie的产生也是HTTP的特点所决定的。HTTP协议有一个非常重要的特点是无状态的,也就是说当客户端请求服务器,每一个请求和响应结束以后,这次的连接是马上断开的(也是为了释放资源)。同时服务器是不保留连接者相关的信息。这就说明了,Cookie要解决HTTP无状态的问题。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AZR8pAxa-1635505515691)(img\3-7cookie的现实场景.jpg)]

特点

  • 含有过期时间(默认关闭浏览器,Cookie销毁)
  • 大小限制在4KB左右 / 数量限制:最多不能超过50个Cookie : 根据浏览器的不同会不同。
  • 存储在客户端
  • Cookie只能存储字符串
  • 不同的浏览器之间不共享Cookie
  • 存储Cookie后在整个项目中有效(页面之间共享)
  • /同localStorage

应用场景

最最常见的就是,表单传递了用户名和密码参数,服务器要在对应的/login路由中判断用户名和密码是否验证成功,成功以后才能告诉浏览器(要保存一个用户状态):后端决定是否存储这个状态。

其实咱们第2阶段学的localStorage 和cookie是很像的。比如:在同一个项目中本地存储共享的。

cookie实现原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s3ctrkr9-1635505515693)(img\3-8Cookie实现流程.jpg)]

cookie-parser

下载

npm install cookie-parser

引入并开启cookie功能

const cookieParser = require("cookie-parser"); // 引入cookieparser中间件
app.use(cookieParser()); // 使用cookie-parser中间件 全局开启cookie功用

设置cookie

 res.cookie(key,value[,option])

参数说明:

​ option:可选参数,{ maxAge : ms} 过期时间,表示多长时间后过期。以毫秒为单位

获取cookie

req.cookies  

完整示例


const cookieParser = require('cookie-parser')
//3. 使用cookie中间件
app.use( cookieParser() )

// 给定一个setcookie路由,它保存一个cookie( username:'zs' )
app.get('/setcookie',(req,res)=>{
    //res.cookie( key,value )
     res.cookie('username','aa')
     res.cookie('username','bb') //之前有username则覆盖
     res.cookie('age',20) //虽然是20,但也是存储为字符串类型

    res.send('设置了cookie')
})

app.get('/setcookie2',(req,res)=>{
    //演示过期时间
    //含有过期时间(默认关闭浏览器,Cookie销毁)
    //res.cookie( key,value[,options] ) //options{ maxAge:过期时间的 } 以毫秒为单位

    res.cookie( 'a',1 )
    res.cookie( 'b',2,{ maxAge:10*1000 } ) //10秒钟过期
    res.send('设置cookie')
})

//给定一个getcookie路由,返回zs
app.get('/getcookie',(req,res)=>{
    //req.cookies 获取所有的cookie
    // res.send('返回cookie:xxx')
    console.log( req.cookies )
    res.send(req.cookies) //它是个对象
})

案例

1)/login路由中通过req.cookie方法设置cookie

2)/welcome路由中设置欢迎界面

3)设计“/user/edit”路由,如果登录了可以正常访问,如果未登录则不让访问(权限管理雏形)


const cookieParser = require('cookie-parser')

app.use( cookieParser() )

// /login : 实现登录(保存cookie)
app.get('/login',(req,res)=>{
    res.cookie( 'username','zs' )
    res.send('登录成功')
})

// /welcome : 欢迎您:xxx, 未登录显示:游客
app.get('/welcome',(req,res)=>{

    if( !req.cookies.username ){//取反为真代表未登录,代表username没有存储值
        res.send('欢迎您:游客')
    }else{
        res.send('欢迎您 VIP:' +req.cookies.username  )
    }

})

// /user/edit: 用户编辑 ,如果未登录显示请登录
app.get('/user/edit',(req,res)=>{
    if( !req.cookies.username ){ 
        res.send('请登录跳转到某个页面')
    }else{
        res.send('可以看到用户编辑的表单页面'  )
    }
})

session

介绍

Session是另一种记录用户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。当服务端使用Session后,那么服务器会把Session信息存储在服务器上,同时Session标识也会记录在对应客户端上。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-td7GHYEL-1635505515696)(img\3-12session的现实场景.jpg)]

而储物柜给你条形码就可以理解为是 sessionid标识(理解为一把钥匙)。

session比cookie相对更安全。

特点

  • Session存储在服务器

  • 依赖cookie

  • 可以存储任意类型

  • 通过客户端的sessionid标识符区分Session

  • Session没有大小限制

  • 不能设置过期时间(关闭浏览器销毁)

  • 不同的浏览器之间不共享Session

  • 存储session后在整个项目中有效(页面之间共享)

应用场景

用cookie实现的那么session也都能实现 。而后端经常会使用session。

实现原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yw8q8cmL-1635505515697)(img/session.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zcT99hxV-1635505515698)(img\3-14Session实现流程.jpg)]

cookie-session

下载

npm i cookie-session

引入并开启session功能

const cookieSession = require("cookie-session"); // 引入cookieSession中间件

// 使用cookieSession 中间件
app.use(cookieSession({
  //而且对象中必须要有keys属性,keys属性是个数组,数组中可以有任意个字符串值,用来加密session。
  name: 'sessionids',//sessionid的名称,默认可以省略
  keys: ['secret1','secret2','secret3'], //密钥锁
}))

设置Session数据

req.session[key] = value 

访问Session数据

req.session 
//1. 下载cookie-session中间件
//2. 引入
const cookieSession = require('cookie-session')
//3. 使用中间件  cookieSession在调用的时候必须传递一个对象
    
app.use( cookieSession({
    keys:['adfsdf','adfsafd','asdfsa'],//给session钥匙进行加密 
    name:'aabbccddadf' ,//可传可不传,可以设置这把钥匙的名称 express:sess.sig/express:sess
}) )


app.get('/setsession',(req,res)=>{
    //设置一个session
    req.session.a=123
    req.session.b='5555'  //虽然可以存储任意类型,但很少存储函数的。
    res.send('把数据存储到session中')
})

app.get('/getsession',(req,res)=>{
    // res.send('得到session数据')
    res.send( req.session )
})

模板引擎(ejs)

简介

渲染页面数据

使用步骤

1.下载ejs

npm i ejs
  1. 在项目中设置ejs模板引擎
app.set('view engine', 'ejs')

3.在项目根目录下创建views文件夹

4.在views文件夹下创建模板文件

​ 必须以 .ejs为后缀名

ejs语法

渲染语法

res.render('模板名称' [, data ])

参数说明:

​ 参数1为模板名称,不需要添加后缀,会自动寻找对应后缀为.ejs文件

​ 参数2为对象,向模板中传递的数据。

//之前我们的html中只是涉及到login.html和register.html
//而且拼接字符串也比较麻烦 。

app.set('view engine','ejs')

//为每一个页面设置路由 login
app.get('/login',(req,res)=>{
    //页面必须在views中。
    res.render('login') //我们可以使用render方法 进行渲染对应的ejs页面 文件必须以ejs后缀
                        //res.render( 无需加后缀 )
})

模板语法

数据渲染
<%=变量名 %> //不限形式,在字符串里写也可以写变量
分支
<% if( 条件 ){%>


<% }else{ %>
     

<% } %>
循环
<% for(let i=0;i<数组.length;i++){ %>

 	循环项           

<% }%>
包含文件

说明:包含文件也是.ejs文件,无需携带后缀名

<%- include('公共文件路径')  %>

示例

<body>
    <%- include('header') %>
    <%- include('footer') %>

    <!-- 1. 渲染变量数据 -->
   用户名: <%= username %>
    <h2> 年龄: <%= age %></h2>
    <!-- 变量可以写在字符串里 -->
  <img width="100" height="100" src="/uploads/<%= persons[i].avatar %>" alt="">

    <!-- 2. 分支 if else -->
    <% if( isPerson ){ %>
    <h2>是个人</h2>
    <% }else{ %>
    <h3>是个猴</h3>
    <% } %>

    <!-- 3. 循环 -->
    <% for( let i=0;i<persons.length;i++ ){ %>
    <h4>姓名:<%= persons[i].username %>, 年龄:<%= persons[i].age %></h4>
    <% } %>

    <!-- 4. 对象 -->
    <div>姓名:<%= person.username %>, 年龄:<%= person['age'] %>, 性别:<%= person.sex %></div>
</body>

express脚手架

  • 普通创建:下载express( 引入express、实例app、开启端口 )、模块化路由、定义post中间、设置cookie、设置ejs、大管家(package.json)

  • 生成器工具express-generator(又称为脚手架工具) 可以快速创建一个应用的骨架,增加开发效率。

使用步骤

1.1 全局安装express-generator

 npm i express-generator -g

1.2 使用脚手架初始化项目

express --view=ejs 项目包名

1.3 进入目录, 安装所有需要的模块

cd 项目包名 
npm install

1.4 启动项目

npm run start  
  • 注:启动项目不能用node app.js,因为脚手架里app.js文件没开端口,端口在www里写着。

1.5 浏览器访问,默认3000端口

目录及文件介绍

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fsbhJcRn-1635505515700)(C:/Users/Administrator/Desktop/%E8%AF%BE%E5%A0%82%E7%AC%94%E8%AE%B0/%E7%AC%AC%E4%B8%89%E9%98%B6%E6%AE%B5/show/this-is-the-803-web-notes/day09/%E7%AC%94%E8%AE%B0/assets/1634694442309.png)]

bin/www :启动文件

app.js:项目入口文件,初始化|全局的工作在app.js中进行定义

koa框架

​ Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。

数据请求方式总结 (post,get)

请求方法编码格式前端要传输的数据格式后端如何获取应用场景
GETurl地址后面(querystring)url?key1=value1&key2=value2不需要中间件 :req.query获取数据
POSTapplicaion/x-www-form-urlencodedform-data: key1=value1&key2=value2express.urlencoded( { extend:true } ) :res.body提交数据
POSTapplicaion/json(只能通过ajax)request-payload: ‘{ “key1”:“value1”,“key2”:“value2” }’express.json() :res.body
POSTmutilpart/form-data(可以使用表单)文件流formidable : 实例对象.prase里的第二个参数文件上传
DELETE同post删除数据
PUT同post更新数据

.body | |
| POST | mutilpart/form-data(可以使用表单) | 文件流 | formidable : 实例对象.prase里的第二个参数 | 文件上传 |
| DELETE | 同post | | | 删除数据 |
| PUT | 同post | | | 更新数据 |

面试题:cookie/session/localStorage的区别

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值