form表单刷新_《大胖 ? 小课》- 不用 js 实现文件无刷新上传

这是《大胖小课》栏目的专题一《说说文件上传那些事儿》的第3节-《不用 js 实现文件无刷新上传》

专题已经更新章节:

《大胖 • 小课》- 我是这样理解文件上传的

《大胖 • 小课》- 写一个 node 的文件上传接口

上一节,我们实现了一个简单的文件上传接口,服务端的文件保存我们使用koa-body来完成。

从这节开始我们开始进行梳理前端各种文件上传的场景。

既然要说不用 js 实现文件无刷新上传,那就要先说说最原始的文件上传,也就是在 ie 时代是怎么处理的。

最原始的文件上传

使用 form 表单上传文件

ie时代,如果实现一个无刷新的文件上传那可是费老劲了,大部分都是用 iframe 来实现局部刷新或者使用 flash 插件来搞定,在那个时代ie 就是最好用的浏览器(别无选择)。

DEMO

b693d55cdf1279bdeb243ee092a6f6cb.gif

这种方式上传文件,不需要 js ,而且没有兼容问题,所有浏览器都支持,就是体验很差,导致页面刷新,页面其他数据丢失。

HTML

<form method="post" action="http://localhost:8100" enctype="multipart/form-data">

        选择文件:
            <input type="file" name="f1"/> input 必须设置 name 属性,否则数据无法发送<br/>
<br/>
            标题:<input type="text" name="title"/><br/><br/><br/>

        <button type="submit" id="btn-0">上 传</button>

</form>

多文件上传

ie 时代的多文件上传是需要创建多个 input file 标签,现在 html5只需要一个标签加个属性就搞定了,file 标签开启multiple

DEMO

99477af3a8f159460e07e969488765e8.gif

HTML

//设置 multiple属性
<input type="file" name="f1" multiple/>

NODE

文件上传接口也需要进行简单的调整,由单文件对象的获取变为多文件数组,然后进行遍历处理。

//中间件处理文件重命名
app.use((ctx) => {

    var files = ctx.request.files.f1;// 多文件, 得到上传文件的数组
    var result=[];

    //遍历处理
    files && files.forEach(item=>{
        var path = item.path;
        var fname = item.name;//原文件名称
        var nextPath = path + fname;
        if (item.size > 0 && path) {
            //得到扩展名
            var extArr = fname.split('.');
            var ext = extArr[extArr.length - 1];
            var nextPath = path + '.' + ext;
            //重命名文件
            fs.renameSync(path, nextPath);
            //文件可访问路径放入数组
            result.push(uploadHost+ nextPath.slice(nextPath.lastIndexOf('/') + 1));
        }
    });

    //输出 json 结果
    ctx.body = `{
        "fileUrl":${JSON.stringify(result)}
    }`;
})

CODE

https://github.com/Bigerfe/fe-learn-code/tree/master/src/upfiles-demo/demo2

局部刷新(不用 js 的无刷新上传) - iframe

这里说的是在 ie 时代的上传文件局部刷新,借助 iframe 实现。

DEMO

9bc99b934003865cecdaf882f78d3c53.gif
  • 局部刷新

页面内放一个隐藏的 iframe,或者使用 js 动态创建,指定 form 表单的 target 属性值为iframe标签 的 name 属性值,这样 form 表单的 shubmit 行为的跳转就会在 iframe 内完成,整体页面不会刷新。

  • 拿到接口数据

然后为 iframe 添加load事件,得到 iframe 的页面内容,将结果转换为 JSON 对象,这样就拿到了接口的数据

HTML

<iframe id="temp-iframe" name="temp-iframe" src="" style="display:none;"></iframe>
        <form method="post" target="temp-iframe" action="http://localhost:8100" enctype="multipart/form-data">
        选择文件(可多选):
            <input type="file" name="f1" id="f1" multiple/><br/> input 必须设置 name 属性,否则数据无法发送<br/>
<br/>
            标题:<input type="text" name="title"/><br/><br/><br/>

        <button type="submit" id="btn-0">上 传</button>

        </form>


<script>

var iframe = document.getElementById('temp-iframe');
iframe.addEventListener('load',function () {
      var result = iframe.contentWindow.document.body.innerText;
      //接口数据转换为 JSON 对象
      var obj = JSON.parse(result);
      if(obj && obj.fileUrl.length){
          alert('上传成功');

      }
      console.log(obj);
});


</script>

NODE

服务端代码不需要改动,略.

CODE

https://github.com/Bigerfe/fe-learn-code/tree/master/src/upfiles-demo/demo3

小结

本节主要是介绍了下在 ie 时代通常是怎样实现文件上传和无刷新上传的,虽然现在的大前端时代已经支持体验更好的方式实现,但是本质的原理都不会变,只是工具(浏览器)升级了。


作者 zz_jesse, 专注前端领域,深更原理和实现,目前在公司主要负责技术架构和团队管理。

个人开源项目 :react ssr 开发骨架 Zz.js, https://github.com/Bigerfe/koa-react-ssr

个人公众号:@《前端张大胖》 欢迎关注,深度好文以及各种福利在等你。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值