表单上传文件 nodejs express Vue 优化

表单文件上传

之前发布过一篇文章是关于文件上传的,但是虽然可以实现,但是存在一些需要优化的地方,这次讲一讲。

还是先上代码:

后端nodejs+express:

在根目录下新建文件server.js

var express = require('express');
var app = express();
var fs = require("fs");

var bodyParser = require('body-parser');
var multer  = require('multer');
const path = require('path');

app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(multer({ dest: '/tmp/'}).array('image'));

app.all('*', function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By", ' 3.2.1');
    res.header("Content-Type", "application/json;charset=utf-8");
    next();
});

app.post('/file_upload', function (req, res) {
    console.log("req")
    console.log(req)
   console.log(req.files[0]);  // 上传的文件信息
   console.log(req.body.username);  //对应用户的username 使得上传的文件唯一
   
   req.files[0].originalname=req.body.username+req.files[0].originalname;//修改上传文件名
   var des_file = __dirname + "/static/upload/" + req.files[0].originalname;
   fs.readFile( req.files[0].path, function (err, data) {
        fs.writeFile(des_file, data, function (err) {
         if( err ){
              console.log( err );
         }else{
               res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});//设置response编码为utf-8
            //    response ={message:'File uploaded successfully', filename:req.files[0].originalname,des_file:des_file};                           
               response =des_file;
            //    return "redirect:/#/";
                      }
          console.log( response );
          res.end( JSON.stringify( response ) );

       });
   });
})


var server = app.listen(8081, function () {

  var host = server.address().address
  var port = server.address().port

  console.log("应用实例,访问地址为 http://%s:%s", host, port)

})

前端vue代码:

<template>
  <div class="hello">
    <h1>核酸检测报告上传</h1>
<form action="http://127.0.0.1:8081/file_upload" method="post" enctype="multipart/form-data" target="nm_iframe" >
<!-- <p>文件请命名为:核酸检测报告</p> -->
<input type="file" name="image" id="f" size="50" />
<br />
<!-- 重命名: -->
<input type="text" name="username" v-model="username"   >
<!-- <p>{{username}}</p> -->
<button type="submit" name="nm_submit" @click="getinfo" >上传文件</button>
</form>
  <iframe id="id_iframe" name="nm_iframe" hidden >  </iframe>


<a :href="fileurl" target="_block">下载附件</a>

</div>
</template>

<script>
import axios from 'axios'

export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App',
      username:"",
      filename:"",
      fileurl:""
    }
  },
  mounted(){
  },
   methods: {    
     
    getinfo(){
      this.$message.success("文件上传成功!")
       var f = document.getElementById("f").files;
        alert(f[0].name);  
        console.log(f[0])
        this.filename=f[0].name
        this.fileurl="上传文件的地址为:"+'../../static/upload/'+this.username+this.filename
        console.log(this.fileurl)
    }
     }
   }
  
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
  font-weight: normal;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

由于form表单提交后,页面会自动跳转到action所对应的地址,为了让表单提交且页面不跳转,我通过添加一个iframe控件的方法实现,

原理就是,action跳转的页面直接展示在iframe中,这样父页面就不会进行跳转。

之后还遇到遇到一个问题就是,由于是iframe空间获取返回值,所以对于取到form表单的返回值就变得十分困难,由于iframe相当于另外一个页面,所以当尝试获取iframe页面中的值的时候,会出现跨域的问题(后台服务启动在8081端口,vue页面启动在8080端口)

解决办法:由于我们的返回值是文件的名字和地址,那么我们就可以直接在文件提交时,获取到文件的信息,通过

 var f = document.getElementById("f").files;  
18         //上次修改时间  
19         alert(f[0].lastModifiedDate);  
20         //名称  
21         alert(f[0].name);  
22         //大小 字节  
23         alert(f[0].size);  
24         //类型  
25         alert(f[0].type); 

我们就可以获取所上传文件的所有信息。 这样就不需要抓取后台的返回值。

这样我所需要的上传文件的地址和名称我就都解决了。这个问题也是通过各种学习,花费了2天的时间才解决,希望可以帮助到有需要的人。

这里再提供一些关于文件的其他方法:

判断文件类型

var type=(src.substr(src.lastIndexOf("."))).toLowerCase();
32 if(type!=".jpg"&&type!=".gif"&&type!=".jpeg"&& type!=".png"){
33 alert("您上传图片的类型不符合(.jpg|.jpeg|.gif|.png)!");
34 return false;
35 }

利用image属性来获取input file里文件的大小:

<script type="text/javascript"> 
function getFilePath(filePath)
{
var image=new Image();
image.dynsrc=filePath;
alert(image.filePath);
}
</</SPAN>script> 
<body> 
<INPUT TYPE="file" NAME="file" SIZE="30" onchange="getFileSize(this)"> 
</</SPAN>body> 
<script type="text/javascript">
function getFileSize(fileObj)
{
var image=new Image();
image.dynsrc=fileObj.value;
alert(image.fileSize || fileObj.files[0].fileSize);
}
<script>
<body>
<INPUT TYPE="file" NAME="file" SIZE="30" onchange="getFileSize(this.value)">
<body>

这里感谢@ghfjj提供的文件名称获取方法

相关文章

根据官网 入门 express
java叫接口control什么的app.get.post等等都是请求方式我们可...
为了前端丢进去的时候可以直接判断中间件就是经过了这个就会...
Express 文件的上传和下载
运行命令下载app.js 增加中间件。
基本模板来的 后面用后就有什么加什么都行。