前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >纯前端实现保存表单数据功能

纯前端实现保存表单数据功能

作者头像
IMWeb前端团队
发布2017-12-29 14:43:25
1.9K0
发布2017-12-29 14:43:25
举报
文章被收录于专栏:IMWeb前端团队IMWeb前端团队

最近在用管理后台配置数据时,发现辛辛苦苦配置好的表单无缘无故地被覆盖,之后了解到由于我们都是在同一台开发机上做开发,难免会遇到其他同学做数据变更时覆盖掉自己的配置数据。于是我决定在表单配置里增加一项“配置操作”功能来解放自己双手以及惠及他人。

用什么方式保存?

  1. 找后端同学去帮忙做保存?
  2. 把配置数据都保存到 localStorage?
  3. 把配置数据都保存到本地文本?

然而看到后端同学繁忙的景象之下,默默地放弃了,所以忽略第一点。如果把数据都保存到 localStorage,那么我是不是还要做一个界面来管理这个配置数据的版本呢,而且还可以选中某个版本快速还原,但这些都需要一定的工作量,localStorage 的数据也不方便导出给别的同学。如果我只用前端技术直接把配置文件保存到本地,那前面两个问题都不存在了,还会带来一个好处就是:拿到这些文件,发布到现网时我可以直接导入,而后端同学只需要运行创建表文件和上传相关的java文件就足够了,减少后端同学的工作量。

实现方式

回想时以前做过的一个需求:当用户点击链接时是下载一个PDF文件,而不是直接使用自带的PDF阅读器打开。

使用a标签的download属性(Chrome和FF已支持),如:

代码语言:javascript
复制
<a href="/uploadfolder/lalala.pdf" download="filename.pdf">点击下载</a>

这明显需要服务器来支持。我们知道href属性可以是一个链接,也可以是一个锚点、伪协议。

但也可以是blobURI、dataURI、fileURI

如果要实现前端保存文本,那么使用dataURI即可实现。 dataURI 的语法结构如下:

代码语言:javascript
复制
data:[<mediatype>][;base64],<data>

如果想了解更多关于data URI的知识,可以点击这里

下载指定的文本的需求就可以快速实现了:

代码语言:javascript
复制
<a href="data:text/plain,text_text_text_text" download="filename.txt">点击下载</a>

如果想通过调用的方式来触发,需要稍微封装:

代码语言:javascript
复制
function downloadText (fileName, textCtx) {
    var aTag;

    if (fileName && textCtx) {
        aTag = document.createElement('a');
        aTag.setAttribute('href', 'data:text/plain,' + textCtx);
        aTag.setAttribute('download',  fileName);
        aTag.click();
    }
}

虽然管理后台不需要支持IE,但这里顺便扯一下IE,IE要达到该效果需要借助execCommand

基本思路是创建一个隐藏iframe并添加到页面上,把需要保存的内容写到iframe内并调起iframe的execCommand命令来保存页面。

代码语言:javascript
复制
var ifr = document.createElement('iframe');

ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.contentWindow.(textCtx);
ifr.contentWindow.document.execCommand('SaveAs', false, fileName);
document.body.removeChild(ifr);

如果你想了解更多关于IE下的execCommand,可以点击这里

整理上述:

代码语言:javascript
复制
function downloadText (fileName, textCtx) {
    var aTag, ifr;

    if (fileName && textCtx) {
        if (!~navigator.userAgent.indexOf('MSIE')) {
            aTag = document.createElement('a');
            aTag.setAttribute('href', 'data:text/plain,' + textCtx);
            aTag.setAttribute('download',  fileName);
            aTag.click();
        } else {
            ifr = document.createElement('iframe');
            ifr.style.display = 'none';
            document.body.appendChild(ifr);
            ifr.contentWindow.(textCtx);
            ifr.contentWindow.document.execCommand('SaveAs', false, fileName);
            document.body.removeChild(ifr);
        }
    }
}
//let's go 
downloadText('lala.txt', 'dolemifaso');

关于读取

使用FileReader可以快速实现,基本思路是 input -> onchange -> new FileReader() -> onload -> readAsDataURL

关于FileRader和相关例子, 可以点击这里

关于发送

这里使用了FormDataXMLHttpRequest 如果你想了解更多关于FormData, 可以点击这里

代码语言:javascript
复制
function postForm (formData) {
    var separator, postTarget, rKV, oForm, oReq, keyVals;

    if (formData && ~formData.indexOf(separator)) {
        separator = '____|____'; //每个字段的链接符,如: 'a:1____|____b:{"c":"d"}'
        postTarget = 'http://test.com/update.do';
        rKV = /([^:]+):([\s\S]+)/;
        oForm = new FormData();
        oReq = new XMLHttpRequest();
        keyVals = formData.split(separator); //切割为 [a:1, b:{"c":"d"}]

        keyVals.forEach(function (keyVal) {
                var pairs = keyVal.match(rKV);

                if (pairs) {
                    oForm.append(pairs[1], pairs[2]);
                }
        });

        //here we go
        oReq.open("POST", postTarget);
        oReq.send(oForm);
        oReq.onload = function (data) {
            var resText, resData;

            if (data.target.status === 200
                && data.target.readyState === 4) {
                resText = data.target.responseText;
                resData = JSON.parse(resText);

                if (resData.retcode === 0) {
                    alert('导入配置成功');
                } else {
                    alert('导入配置失败:' + resText);
                }
            }
        }
    } else {
        alert('文件格式不合法');
    }
}

全文完

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 用什么方式保存?
  • 实现方式
  • 关于读取
  • 关于发送
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档