开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 17 天,点击查看活动详情
文件上传格式
前后端数据传输一般有以下格式 formData x-www-form-urlencoded json 普通文本字符串 Buffer
但是文件上传一般都是formData也可以是buffer
demo
const fm = new FormData()
fm.append('key', 'value'),
fm.append(filename, file)
return axios.post('http://127.0.0.1:8888/upload_single', fm, {
headers: {
"Content-Type": "mutipart/form-data"
}
})
文件类型 axios 封装
如果大多情况下上传的都是文件类型,那么axios默认的header就设置成 "Content-Type": "mutipart/form-data"。 如果有urlencoded形式传的参数,就在请求拦截器里统一使用qs将josn转换成urlencoded格式。
import axios from 'axios'
import Qs from 'qs'
const urlencodedHeader = {
"Content-Type": "application/x-www-form-urlencoded"
}
const uploadHttp = axios.create({
baseURL: "http://127.0.0.1:8888",
timeout: 5000,
headers: {
"Content-Type": "mutipart/form-data"
},
transformRequest (data, headers) {
const contentType = headers['Content-Type']
if (contentType === urlencodedHeader['Content-Type']) {
return Qs.stringify(data)
}
return data
}
})
export const uploadSingle = (fm) => {
return uploadHttp.post('/upload_single', fm)
}
基础操作
单文件上传直接上传就行了 为了好看一般ui库都会隐藏掉input标签,然后搞一个button按钮,当用户点击这个按钮时,手动触发这个input的click时间,因为input的类型是file类型,默认动作就是唤起文件选择,选择文件后,会触发input的change事件,然后在change事件里拿到e.target.file,从而拿到了文件对象,拿到这个对象后存到状态里,然后点击上传按钮后,使用new FormData 创建一个formData对象,里面append 文件的key和value 并且调用文件上传接口,将这个文件对象传给后端,后端接收一下就完成了文件上传
<section className="upload_box">
<input
ref={input1}
type="file"
onChange={handleChange1}
className="upload_inp"
/>
<div className="upload_button_box">
<div
className="upload_button select"
onClick={() => input1.current.click()}>
选择文件
</div>
<div className="upload_button upload" onClick={handleUploadSingle}>
上传到服务器
</div>
</div>
<div className="upload_tip">
只能上传png/jpg/jeeg格式图片,且图片不能超过2MB
</div>
<ul className="upload_list">
{Array.from(fileList1).map((item) => {
return <li key={item.name}>{item.name}</li>
})}
</ul>
</section>
状态和方法
const input1 = useRef()
const [fileList1, setFileList1] = useState([])
const handleChange1 = (e) => {
setFileList1(e.target.files)
}
const handleUploadSingle = async () => {
let formData = new FormData()
formData.append('file', fileList1[0])
const res = await uploadSingle(formData)
}
文件上传原理分析
(1)文件上传方式有很多,但底层的实现都是文件的读写操作(I/O读写)
文件上传的必要前提 1) 提供form表单、method必须是post 2) form表单的entype必须是multipart/form-data 3) 提供input type=“file”类的上传输入域
(2)文件上传到本地服务器的缺点:
-
当服务器重启,本地服务的文件没了
-
搭建服务器集群:A服务器1000, B服务器......... 客户第一次上传时访问的是A服务器。 客户第二次访问文件,访问的是B服务器
(3)如何解决本地服务器上传的缺点:
(1)自己搭建一个文件服务器;不会重启,维护
(2) 使用第三方的文件服务器