js 中 文件流的截取处理

问题背景:

项目开发的中有一个这样的场景,在前端页面中实现一个markdown的文本编辑器,对md文件进行编辑、预览和保存。在看了github上的issue模块以及一些论坛的回复功能模块。基本的实现流程是这样的。现在以markdown为例:

1、后端将存在数据库中的md文件解析成json格式的字符串(.md源码)传给前端
2、前端接收到 .md 源码的字符串 进行编辑,完成之后 点击保存将 编辑后的 .md 源码的字符串 传给后端服务器
3、后端将 .md 源码的字符串生成 .md 的文件存在数据库

可以看到整个过程中前端的处理很简单,仅仅是对字符串进行处理,难点无非是自己实现一个markdown编辑器插件或者从网上找一个插件。而所有的文件解析处理工作全部放后端来处理。

这个需求实际是一个优化需求,之前是不支持展示和编辑功能,仅仅是一个.md文件的上传和下载。在后端功能不变(即仅提供文件的存取功能)的情况下实现这个需求,这些解析工作就需要放前端来处理了。

解决思路:

1、将下载.md文件的过程,转为截取文件流 转为md源码字符串作为一个变量存在内存中
2、对字符串进行处理后 转为.md文件上传后端。

前端获取文件一般都是用动态生成a标签,或者iframe标签来进行下载 如

// iframe的方式
function createDownloadIframe (src, showModal) {
  const target = document.getElementById('downIframe')
  if (target) {
    document.body.removeChild(target)
  }
  const htm = document.createElement('iframe')
  htm.setAttribute('src', src)
  htm.setAttribute('id', 'downIframe')
  htm.style.display = 'none'
  document.body.appendChild(htm)
  if (htm.attachEvent) {
    htm.attachEvent('onload', () => {
     ...
    })
  } else {
    htm.onload = () => {
     ...
    }
  }
}

// a标签的方式
const a = document.createElement('a'); // 创建a标签
a.setAttribute('download', ''); // download属性
a.setAttribute('href', ''); // href链接
a.click();// 自执行点击事件

现在这一步需要做的操作就是下载过程转为获取流过程

// 用原生js的XMLHttpRequest 发送请求的方式:
function catchBinary (url) {
let xmlHttpRequest = new XMLHttpRequest()
  xmlHttpRequest.open('GET', url, true)
  xmlHttpRequest.setRequestHeader('Content-type', 'application/json')
  xmlHttpRequest.responseType = 'blob'
  xmlHttpRequest.onload = function (oEvent) {
    let content = xmlHttpRequest.response
    let reader = new FileReader()
    reader.readAsText(content)
    reader.onload = function (evt) {
      if (evt.target.readyState === FileReader.DONE) {
        cb && cb(reader.result)
      }
    }
  }
  xmlHttpRequest.send()
}

// 因为本项目为vue + axios 项目所以 用axios封装好的方法
getMDFileBinary (url) {
  return axios({
    method: 'get',
    url: url,
    responseType: 'blob'
  })
}
getMDFileBinary(url).then(response => {
      let reader = new FileReader()
      reader.readAsText(response.data)
      reader.onload = function (evt) {
        if (evt.target.readyState === FileReader.DONE) {
          __this.value = reader.result
        }
      }
    })

这样第一步获取工作就完成了,接下来进行第二步

第二步 将字符串生成文件并上传

// 处理文件
const md = this.md // md 源码 (本项目为 vue项目 this.md)
const mdFile = new File([md], 'text.md')
let formData = new FormData()
formData.append('file', mdFile )
setMDFileBinary(url, formData).then(res => {
	console.log(res.data)
})
function setMDFileBinary (url, data) {
  return axios({
    method: 'post',
    url: url,
    data: data,
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  })
}

DONE。。。
这样基本的功能就完成了

TODO

1、兼容性问题: mavon-editor 不支持ie浏览器
2、。。。

知识点和工具:

一款markdown编辑器 mavon-editor
axios
Blob
FileReader
XmlHttpRequest
FormData
File

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值