前后端上传文件操作

tech2022-08-10  139

0-0.文件上传

0-1.了解文件上传

在前端把本地的 img 视频 音频 之类的文件,发送给服务端, 服务端存储在服务器里面,把文件地址存储在数据库里面

1-0.前端文件上传

1-1. 直接使用 form 表单上传

表单直接上传 form 标签的设置 action 设置服务器地址 method POST 方式 enctype mutilpart/form-data 属性规定在发送到服务器之前应该如何对表单数据进行编码。 => enctype 设置请求头中的 content-type => mutilpart 设置以二进制流的形式上传 input => type 选择成 file => name 设置一个名字 <form action="http://localhost:8080/upload" method="POST" enctype="multipart/form-data"> <input type="file" name="avatar"> <input type="text" name="username"> <button>上传</button> </form>

1-2. 原生 JS 上传文件

原生 js 上传 需要用 HTTP/2.0 的技术 一个内置构造函数叫做 FormData() => 语法: new FormData(form元素) => 返回一个包含 form 元素里面所有带有 name 属性元素的值 => 直接打印看不到 <form> <input type="file" name="avatar"> <input type="text" name="username"> <button>上传</button> </form> <script> // 1. 获取元素绑定事件 const form = document.querySelector('form') form.addEventListener('submit', function (e) { e.preventDefault() // 2. 拿到文件 const formData = new FormData(this) // 3. 正常 ajax 发送 const xhr = new XMLHttpRequest() xhr.open('POST', '地址') // 不需要单独设置请求头 // 因为 formData 会自动设置请求头 xhr.send(formData) xhr.onload = function () { } }) </script>

1-3. jQuery 上传文件

jquery 上传和原生 js 基本一致 绑定事件 使用 FormData() 拿到数据 使用 $.ajax() 问题 + formData 会自动设置请求头, 但是 jquery 也会 => jquery 会默认设置程 application/x-www-form-urlencoded + formData 会发送 二进制流 的形式 => jquery 会把所有的数据给你直接格式化成 key=value&key=value <form> <input type="file" name="avatar"> <input type="text" name="username"> <button>上传</button> </form> <script src="../../node_modules/jquery/dist/jquery.min.js"></script> <script> $('form').submit(function (e) { e.preventDefault() const formData = new FormData($('form')[0]) $.ajax({ method: 'POST', url: 'http://localhst:8080/upload', data: formData, contentType: false, // 不要动请求头, 直接上传 processData: false, // 不要管我的数据, 直接上传 success (res) { console.log(res) } }) }) </script>

2-0.后端文件上传

2-1.单文件上传

单文件上传的简单版本

1. 解决跨域问题 + 下载一个包叫做 cors 2. 接收文件 2-1. 我要准备一个文件夹, 在服务器上 => 存储上传的文件 2-2. 需要一个插件帮助 => multer => 下载 => 导入 2-3. 需要使用 multer 配置一个接收器 => multer({ dest: '你存放文件的路径' }) 2-4. 使用接收器去接收文件 => 哪一个路由需要接收文件, 配置在哪一个路由上 => 写在路由标识符的后面, 路由处理函数的前面 => 接收器.single('前端上传的文件的 key') 2-5. 在路由处理函数里面 => 会在 req 上面多家一个信息叫做 file => 就是你上传的文件的信息 注意: 会把你的文件存储起来, 但是没有后缀, 随机命名 // 导入框架 const express = require('express') // 创建路由表 const router = express.Router() // 1. 导入 cors 插件 const cors = require('cors') // 2-2. 导入 multer 插件 const multer = require('multer') // 2-3. 使用 multer 去生成一个接收其 // 我配置的这个接收器, 将来接收到的文件就直接存储在 指定目录 const fileUpload = multer({ dest: '../uploads/' }) // 创建服务 const app = express() // 1. 挂载上 cors 就跨域了 app.use(cors()) // 2-4. 在需要的路由上进行配置 router.post('/upload', fileUpload.single('avatar'), (req, res) => { console.log('接收请求') console.log(req.file) }) // 使用路由表 app.use(router) // 监听端口号 app.listen(8080, () => console.log(8080))

2-2.单文件上传

single 方法是专门接收单文件-------> 一个名称配一个文件

单文件上传的复杂版本 1. 解决跨域问题 下载一个包叫做 cors 2. 接收文件 2-1. 我要准备一个文件夹, 在服务器上 => 存储上传的文件 2-2. 需要一个插件帮助 => multer => 下载 => 导入 2-3. 生成一个仓库信息 => multer.diskDtorage({ 配置 }) => destitnation: function () {} 设定存储路径 => filename: function () {} 设定文件名称 => 返回值: 是一个仓库信息 2-4. 使用 multer 生成一个接收器 => 接收器里面配置一个仓库信息 => 语法: multer({ storage: 仓库信息 }) const express = require('express') const path = require('path') const router = express.Router() // 1. 导入 cors 插件 const cors = require('cors') // 2-2. 导入 multer 插件 const multer = require('multer') // 2-3. 使用 multer 生成一个仓库信息 const storage = multer.diskStorage({ destination: function (req, file, cb) { // req, 本次请求信息 // file, 本次请求的文件 // cb, 回调函数, 利用回调函数来设定存储路径 // 第一个参数 null, 表示不要修改我的 二进制流 文件 cb(null, '../uploads/') }, filename: function (req, file, cb) { // req, 本次请求信息 // file, 本次上传的文件信息 // cb, 回调函数, 通过回调函数来设定文件名称 // 从 file 信息里面把后缀名拿出来, 前面我们自己拼接随机数 const tmp = path.extname(file.originalname) cb(null, `avatar_${ new Date().getTime() }-${ Math.random().toString().slice(2) }${ tmp }`) } }) // 2-4. 配置接收器, 带有仓库信息 const fileUpload = multer({ storage :storage}) const app = express() // 1. 挂载上 cors 就跨域了 app.use(cors()) // 2-5. 使用我们配置好的接收其去接收文件 router.post('/upload', fileUpload.single('avatar'), (req, res) => { console.log('接收请求') console.log(req.file) }) app.use(router) app.listen(8080, () => console.log(8080))

2-3.单名称多文件上传

array 方法是专门接收多文件----> 一个名称配多个文件

单名称多文件上传 1. 解决跨域问题 + 下载一个包叫做 cors 2. 接收文件 2-1. 我要准备一个文件夹, 在服务器上 => 存储上传的文件 2-2. 需要一个插件帮助 => multer => 下载 => 导入 2-3. 生成一个仓库信息 => multer.diskDtorage({ 配置 }) -> destitnation: function () {} 设定存储路径 -> filename: function () {} 设定文件名称 => 返回值: 是一个仓库信息 2-4. 使用 multer 生成一个接收器 => 接收器里面配置一个仓库信息 => 语法: multer({ storage: 仓库信息 }) 2-5. 使用方法发生一些变换 => single 方法是专门接收单文件 -> 一个名称配一个文件 => array 方法是专门接收多文件 -> 一个名称配多个文件 => 在后面的路由处理函数里面就不能接收 req.file -> file 只是接收单文件 -> files 接收多文件(以一个数组的形式, 里面存储着每一个文件信息) const express = require('express') const path = require('path') const router = express.Router() // 1. 导入 cors 插件 const cors = require('cors') // 2-2. 导入 multer 插件 const multer = require('multer') // 2-3. 使用 multer 生成一个仓库信息 const storage = multer.diskStorage({ destination: function (req, file, cb) { // req, 本次请求信息 // file, 本次请求的文件 // cb, 回调函数, 利用回调函数来设定存储路径 // 第一个参数 null, 表示不要修改我的 二进制流 文件 cb(null, '../uploads/') }, filename: function (req, file, cb) { // req, 本次请求信息 // file, 本次上传的文件信息 // cb, 回调函数, 通过回调函数来设定文件名称 // 从 file 信息里面把后缀名拿出来, 前面我们自己拼接随机数 const tmp = path.extname(file.originalname) cb(null, `avatar_${ new Date().getTime() }-${ Math.random().toString().slice(2) }${ tmp }`) } }) // 2-4. 配置接收器, 带有仓库信息 const fileUpload = multer({ storage }) const app = express() // 1. 挂载上 cors 就跨域了 app.use(cors()) // 2-5. 使用我们配置好的接收其去接收文件 router.post('/upload', fileUpload.array('avatar'), (req, res) => { console.log('接收请求') console.log(req.file) console.log(req.files) }) app.use(router) app.listen(8080, () => console.log(8080))

2-4多名称多文件上传

在后面的路由处理函数里面就不能接收 req.file

-> file 只是接收单文件 -> files 接收多文件(以一个数组的形式, 里面存储着每一个文件信息) 多名称多文件上传 1. 解决跨域问题 + 下载一个包叫做 cors 2. 接收文件 2-1. 我要准备一个文件夹, 在服务器上 => 存储上传的文件 2-2. 需要一个插件帮助 => multer => 下载 => 导入 2-3. 生成一个仓库信息 => multer.diskDtorage({ 配置 }) -> destitnation: function () {} 设定存储路径 -> filename: function () {} 设定文件名称 => 返回值: 是一个仓库信息 2-4. 使用 multer 生成一个接收器 => 接收器里面配置一个仓库信息 => 语法: multer({ storage: 仓库信息 }) 2-5. 使用方法发生一些变换 => single 方法是专门接收单文件 -> 一个名称配一个文件 => array 方法是专门接收多文件 -> 一个名称配多个文件 => fields 方法是专门接收多文件 -> 多个名称配多个文件 => 在后面的路由处理函数里面就不能接收 req.file -> file 只是接收单文件 -> files 接收多文件(以一个数组的形式, 里面存储着每一个文件信息) 注意: 涉及到多个名称, 我们要一个一个标志好 const express = require('express') const path = require('path') const router = express.Router() // 1. 导入 cors 插件 const cors = require('cors') // 2-2. 导入 multer 插件 const multer = require('multer') // 2-3. 使用 multer 生成一个仓库信息 const storage = multer.diskStorage({ destination: function (req, file, cb) { // req, 本次请求信息 // file, 本次请求的文件 // cb, 回调函数, 利用回调函数来设定存储路径 // 第一个参数 null, 表示不要修改我的 二进制流 文件 cb(null, '../uploads/' + file.fieldname) }, filename: function (req, file, cb) { // req, 本次请求信息 // file, 本次上传的文件信息 // cb, 回调函数, 通过回调函数来设定文件名称 // 从 file 信息里面把后缀名拿出来, 前面我们自己拼接随机数 const tmp = path.extname(file.originalname) cb(null, `${ file.fieldname }_${ new Date().getTime() }-${ Math.random().toString().slice(2) }${ tmp }`) } }) // 2-4. 配置接收器, 带有仓库信息 const fileUpload = multer({ storage }) const app = express() // 1. 挂载上 cors 就跨域了 app.use(cors()) // 2-5. 使用我们配置好的接收其去接收文件 router.post('/upload', fileUpload.fields([ { name: 'avatar' }, { name: 'photo' } ]), (req, res) => { console.log('接收请求') console.log(req.file) console.log(req.files) }) app.use(router) app.listen(8080, () => console.log(8080))
最新回复(0)