> 文章列表 > 网络请求实战-实战文件上传

网络请求实战-实战文件上传

网络请求实战-实战文件上传

目录

表单提交数据方式

HTML5方式

base64

实战HTML5+base64

HTML5+blob上传

小结


表单提交数据方式

  • FormData是用来表示表单数据的一个对象

里面是Key/value

用Boundary分隔的一段一段数据

  • 观察用表单提交数据时POST到服务端的数据body是怎样的?
  • 观察用表单提交文件时body是怎样的?
  • Express如何接收表单提交的数据?
<!DOCTYPE html>
<html>
<body>
<h2>HTML Forms</h2>
<!-- enctype="multipart/form-data" -->
<form action="/submit" method="POST" enctype="multipart/form-data"><label for="fname">First name:</label><br><input type="text" id="fname" name="fname" value="张"><br><label for="lname">Last name:</label><br><input type="text" id="lname" name="lname" value="三"><br><br><label for="file">file:</label><br><input type="file" id="file" name="file"><br><br><input type="submit" value="Submit">
</form> 
</body>
</html>
const express = require('express')
const fs = require('fs')
const path = require('path')
const bodyParser = require('body-parser')
const fileUpload = require('express-fileupload')
const { urlencoded } = require('express')
const app = express()
// 表单方式
app.get('/submit', (req, res) => {res.sendFile(path.resolve(__dirname, "submit.html"))  // __dirname相对路径
})app.post("/submit",fileUpload(),(req, res) => {console.log(req.files, req.body)req.files.file.mv(path.resolve(__dirname, 'upload/a.jpg'))res.send("ok")}
)app.listen(3000)

HTML5方式

base64

用64个可打印字符(A-Za-z0-9+,=)来编码二进制

0-255的ascii码中有许多不能打印的字符

不能打印的字符就不需要在中间过程中转义,如空格变成%2f

实战HTML5+base64

  • 观察HTML5的文件API使用
  • 观察base64方法
  • 观察直接用流上传的方法
  • base64上传文件会变成4/3大小,文件变大了
<!DOCTYPE html>
<html>
<body>
<h2>HTML Forms</h2>
<div><label for="file">file:</label><br><input type="file" id="file" name="file"><br><br><input onClick='submit()' type="submit" value="Submit">
</div> 
<script>let upload = {}function submit(){console.log('here', upload)fetch('/submitb64', {method : "POST",//body : `name=${upload.name}&data=${upload.data}`,body : JSON.stringify(upload),// base64中是有=的headers : {//'Content-Type' : 'application/x-www-form-urlencoded''Content-Type' : 'application/json'}})}document.getElementById("file").addEventListener('change', e=>{const files = e.target.files// File(Blob)for(let file of files) {const fr = new FileReader()fr.readAsDataURL(file)fr.onload = () => {console.log(fr.result)upload.data = fr.result.substr(22)// 文件类型说明占用字段22个字符upload.name = file.name}}})
</script>
</body>
</html>
const express = require('express')
const fs = require('fs')
const path = require('path')
const bodyParser = require('body-parser')
const fileUpload = require('express-fileupload')
const { urlencoded } = require('express')
const app = express()
// HTML5   base64
app.get('/base64', (req, res) => {res.sendFile(path.resolve(__dirname, "submitb64.html"))
})app.post("/submitb64",bodyParser.json(),(req, res) => {const buffer = new Buffer(req.body.data, 'base64')console.log(req.body.data.length)fs.writeFileSync(path.resolve(__dirname, "upload/x.jpg"), buffer)res.send("ok")}
)
app.listen(3000)

HTML5+blob上传

  • 传输比Base64更快
  • 对CPU压力更小
<!DOCTYPE html>
<html>
<body>
<h2>HTML Forms</h2>
<div><label for="file">file:</label><br><input type="file" id="file" name="file"><br><br><input onClick='submit()' type="submit" value="Submit">
</div> 
<script>let upload = {}function submit(){console.log('here', upload)const formData = new FormData()formData.append('name', upload.name)formData.append('file', upload.data)fetch('/submitbinary', {method : "POST",body : formData,headers : {// 这里如果设置了Content-Type会有Bug// 'Content-Type' : 'multipart/form-data'}})}document.getElementById("file").addEventListener('change', e=>{const files = e.target.filesfor(let file of files) {upload.data = file upload.name = file.name}})
</script>
</body>
</html>
const express = require('express')
const fs = require('fs')
const path = require('path')
const bodyParser = require('body-parser')
const fileUpload = require('express-fileupload')
const { urlencoded } = require('express')
const app = express()// HTML5   binary
app.get('/binary', (req, res) => {res.sendFile(path.resolve(__dirname, "submitbinary.html"))
})
app.post("/submitbinary",fileUpload(),(req, res) => {console.log(req.files, req.body)req.files.file.mv(path.resolve(__dirname, 'upload/b.jpg'))res.send("ok")}
)app.listen(3000)

小结

  • 上传文件和提交输入框中的字段没有本质的区别
  • Base64方法速度慢,没有特殊原因通常用blob上传