前端用FormData实现文件上传以及图片回显

前端实现文件上传的类型为FormData

先熟悉下FormData的API

 var  fd=new FormData()//
fd.apend('name','张三');//为fd对象添加参数,以key=>value的键值对的形式
//或者用fd.set('name','张三')

要获取formData中的值,不能直接打印console.log(fd),这样是打印不出来值的,一定要用get()方法才能获取,或者是用数组的方式遍历
例如fd.forEach()方法

fd.get('user');

开始实现文件上传

前端使用<input type='file'>标签实现上传

 <form id='form'>
        <label>姓名: <input type="text" id='user' name="user" /></label>
        <input type="file" id="foo" name="foo" multiple="multiple">
    </form>

其中multiple="multiple" 的参数表示可以选择多张文件上传
手写ajax代码如下

    var user = document.getElementById('user');
     var file = document.getElementById('foo');
    var btn = document.getElementsByTagName('button')[0];
   btn.onclick = () => {
        var ajx = new XMLHttpRequest();
        ajx.open("post", "/upload", true); //设置请求地址和路径
        var fd = new FormData();
        fd.append('user', user.value);
        fd.append('file',file.files[0]);
        ajx.onreadystatechange = function () {
            if (ajx.readyState == 4 && ajx.status == 200) {
                console.log(ajx);
            }
        }
        ajx.send(fd);
    }

以上代码要把获取的user的值和文件转换成FormData对象,其中获取文件数据是通过[目标元素].files获取,获取的的值是类似于数组,因为可以是多个文件,所有需要做什么操作可以去遍历一遍,要把表单数据统一转换成FormData对象,可以不用append()方法一项项的去添加,可以利用表单元素的属性进行操作

  var fd = new FormData(document.getElementById('form'));

用这种方式每个输入框必须要有name属性,例如<input type='file' name='file'>


image.png

node配置服务端

上传文件需要安装一个中间件处理express-fileupload

npm install express-fileupload --save

早app.js中注册一下
const fileUpload = require('express-fileupload');
app.use(fileUpload());
手写后台接口路由

var express = require('express');
var router = express.Router();
var path=require('path');
router.post('/upload', function(req, res, next) {
   console.log(req.body);
   let f =  req.files.file;
   f.mv(path.join(__dirname,'../public','upload',f.name), function(err) {
       if(err){
           return res.status(400).send("sdsdsdas");
       }
       res.send('文件上传成功!');
   }); 
});

module.exports = router;

以上代码 let f = req.files.file;file为前的FormData对象的键值,
如果要上传多个文件,input只需要加multiple="multiple"属性

<inpurt type='file' multiple="multiple">

后台代码

router.post('/upload', function(req, res, next) {
   let f = req.files.file;
   let newFile =[].concat(f);
   newFile.forEach((file,index)=>{
           file.mv(path.join(__dirname,'../public','upload',file.name), function(err) {
            if(err){
                return res.status(400).send("sdsdsdas");
            }
        }); 
       })
    res.send('文件上传成功!');
});

效果如下图所示


截图录屏_选择区域_20201019193413.gif

image.png

上传图片前的图片回显

有时候需要上传图片,选择图片后需要先显示而不是直接取后台返回来的地址
html代码

<form id='form'>
        <label>姓名: <input type="text" id='user' name="user" /></label>
        <input type="file" id="foo" name="file" multiple="multiple">
    </form>
    <!-- 图片回显 -->
    <div class="image">

    </div>
    <button>提交</button>

js代码

var form = document.getElementById('form');
    var user = document.getElementById('user');
    var btn = document.getElementsByTagName('button')[0];
    var file = document.getElementById('foo');
    var showImg = document.getElementsByClassName('image')[0];
    file.onchange = (e) => {
        const reader = new FileReader();
        reader.readAsDataURL(file.files[0]);
        var img = new Image();
        reader.onloadend = (e) => {
            img.src = reader.result;
            showImg.appendChild(img);
        }
    }
    btn.onclick = () => {
        var ajx = new XMLHttpRequest();
        ajx.open("post", "/upload", true);
        var fd = new FormData(form);
        ajx.onreadystatechange = function () {
            if (ajx.readyState == 4 && ajx.status == 200) {
                console.log(ajx);
            }
        }
        ajx.send(fd);
    }

其中的onChange方法是input标签选择图片时触发,此时需要知道FileReader对象的用法以及API

https://developer.mozilla.org/en-US/docs/Web/API/FileReader
github地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。