fasta文件校验
最近在利用javascripte构建网页blast时候,涉及到客户端文件和表单的提交。因此结合vue与element-ui框架封装了一个上传并对fasta文件进行校验的插件
1.获取文件对象
- 使用拖拽事件,移动文件
dataTransfer.files
获取拖拽文件
1
| this.fileData = e.dataTransfer.files[0]
|
2.读取文件数据
- 使用
FileReader
对象读取文件对象内容
- 作为字符窜进行读取,触发
load
事件
1 2 3 4 5
| var reader = new FileReader() reader.readAsText(fileData, 'utf-8') reader.onload = function () { reader.result }
|
3.匹配核酸序列与蛋白序列
创建正则表达式对核酸序列与蛋白序列进行匹配
- 核苷酸序列,除了
A T C G N
几种碱基外还有换行符\n
i
忽略大小写,m
多行匹配
1
| var Basepattern = /[^ATCGN\n\r]/im
|
1
| var ProteinPattern = /[^GAVLIPFYWSTCMNQDEKRH\\*\r\n]/im
|
- 提取核苷序列与蛋白序列,
slice
忽略第一个空白字符
1
| var sequenceArray = reader.result.split(/>[^\n]+\n/).slice(1)
|
只有序列中有一条满足正则表达式,则表示错误的序列格式;并返回true;
而蛋白序列的校验时还多了一条规则,因为蛋白序列都是以甲硫氨酸开头,并且核酸的基因缩写与氨基酸缩写重叠了不能够区分蛋白序列与氨基酸序列
1 2 3 4 5 6 7
| BaseFlag = sequenceArray.some((sequence) => { return Basepattern.test(sequence) }) ProteinFlag = sequenceArray.some((sequence) => { return ProteinPattern.test(sequence) || /^[^M]/i.test(sequence) })
|
4.回调函数获取校验结果
因为onload函数是异步的,所以有可能出现文件还没校验完,客户端状态就已经发生改变;所以使用回调函数获取校验结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| validateFasta(this.fileData, (BaseFlag, ProteinFlag) => { if (BaseFlag && ProteinFlag) { this.showModal = true this.Modalmessage = 'error fasta file' this.ModalFontColor = { color: '#d63031' } this.Modalicon = 'el-icon-check' setTimeout(() => { this.showModal = false }, 1000) } else if (!BaseFlag) { this.showModal = true this.Modalmessage = 'Nucleic acid sequence file' this.ModalFontColor = { color: '#4cd137' } this.Modalicon = 'el-icon-close' setTimeout(() => { this.showModal = false }, 1000) } else if (!ProteinFlag) { this.showModal = true this.Modalmessage = 'Protein sequence file' this.ModalFontColor = { color: '#4cd137' } this.Modalicon = 'el-icon-close' setTimeout(() => { this.showModal = false }, 1000) } })
|
5.校验完成后将数据提交后台
客户端使用FormData
对象可以同时提交文件与表单,在后台借助connect-multiparty
插件获取上传的文件
- 将文件数据与表单数据合并
- 表单数据需要使用for循环进行包装
如果需要获取FormData已经添加的内容,需要使用get方法;因为添加进去的内容已经变成私有变量无法直接访问。
1 2 3 4 5 6
| const formData = new FormData() formData.append('fastafile', this.$refs.dropfile.fileData)
for (var key in this.formInline) { formData.append(key, this.formInline[key]) }
|
1 2 3 4 5
| request.post('/test', formData).then( () => { console.log('ok') } )
|
测试过程遇到的跨域问题,使用本地代理服务器与后端API进行交互;因为使用浏览器与后端API交互时,浏览器处于安全原因会阻止跨域请求。
配置vue.config.js
配置文件,以及axios的请求地址改成’/api’
1 2 3 4 5 6 7 8
| proxy: { '/api': { target: 'http://后端地址:80', ws: true, pathRewrite: { '^/api': '/' } }
|
6.后端获取数据
- 借助
connect-multiparty
插件,将文件存在/tmp/
目录下
- 借助
body-parse
解析form表单数据
1 2 3 4 5 6 7 8 9 10 11 12
| var multipart = require('connect-multiparty') var fs = require('fs')
var multipartMiddleware = multipart() router.post('/test', multipartMiddleware, function (req, rep) { tmpFilePath = req.files.fastafile.path console.log(req.files) var fasta = fs.readFileSync(tmpFilePath, 'utf-8') console.log(req.body) console.log(fasta) rep.send('test') })
|
7.演示地址
fasta
文件拖拽校验
参考
- 文件拖拽失效解决
- 读取FileList对象内容
- 拖拽事件触发
- axios跨域