了解文件上传情况
- 在前端把本地的img视频,音频之类的文件
- 发送给服务端,服务端存储在服务器里面
- 把文件地址存储在数据库里
前端上传的操作
表单直接上传
- input
- type 选择成file
- name 设置一个名字
- form标签的设置
- action 设置服务器地址
- method POST方式
- enctype multipart/form-data
-
enctype 请求头里面的 content-type
-
multipart 设置以二进制流的形式上传
-
<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>
原生JS上传
- 需要用HTTP/2.0的技术
- 一个内置构造函数叫做FormData()
- 语法:new FormData(form元素)
- 返回一个包含form元素里面所有带有name属性元素的值
- 直接打印看不到
-
获取元素绑定事件
-
拿到文件
-
正常AJAX发送
// 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 () { } })
jQuery上传文件
-
和原生JS基本一致,就是绑定事件
-
使用formData()拿到数据
-
使用$.ajax()
$('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) } }) })
- 问题
- formData 会自定设置请求头,但jQuery不会
- jQuery会默认设置成 application/x-www-form-urlencoded
- formData 以二进制流
- jQuery
后端接收文件以后存储起来
单文件上传
单文件上传的简单版本
-
解决跨域问题
- 下载一个包叫cors
-
接受文件
- 准备一个文件夹,在服务器上存储上传的文件
- 需要一个插件multer 进行下载导入
-
需要使用multer配置一个接收器
- multer(dest:'')}
-
使用接收器接收文件
- 哪一个路由需要接收文件,配置在哪一个文件上
- 写在路由标识符后面,路由出来函数的前面
- 接收器.single('前端上传文件的key‘)
-
在路由处理函数里面
-
会在 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))
-
单文件上传的复杂版本
-
解决跨域问题
- 下载一个包叫cors
-
接受文件
- 准备一个文件夹,在服务器上存储上传的文件
- 需要一个插件multer 进行下载导入
-
生成一个仓库信息
- multer.deskStorage({配置})
- destitnation:function({}) 设置存储路径
- filename:function(){}设定文件名称
- 返回值:是一个仓库信息
- multer.deskStorage({配置})
-
使用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 }) 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))
单名称多文件上传
-
解决跨域问题
- 下载一个包叫cors
-
接受文件
- 准备一个文件夹,在服务器上存储上传的文件
- 需要一个插件multer 进行下载导入
-
生成一个仓库信息
- multer.deskStorage({配置})
- destitnation:function({}) 设定存储路径
- filename:function(){}设定文件名称
- 返回值:是一个仓库信息
- multer.deskStorage({配置})
-
使用multer生成一个接收器
- 接收器里面配置一个仓库信息
- 语法:multer({storage: 仓库信息})
-
使用方法发生一些变换
- 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))
多名称多文件上传
-
解决跨域问题
- 下载一个包叫cors
-
接受文件
- 准备一个文件夹,在服务器上存储上传的文件
- 需要一个插件multer 进行下载导入
-
生成一个仓库信息
- multer.deskStorage({配置})
- destitnation:function({}) 设定存储路径
- filename:function(){}设定文件名称
- 返回值:是一个仓库信息
- multer.deskStorage({配置})
-
使用multer生成一个接收器
- 接收器里面配置一个仓库信息
- 语法:multer({storage: 仓库信息})
-
使用方法发生一些变换
- 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))