node.js+react全栈实践-Form中按照指定路径上传文件并

释放双眼,带上耳机,听听看~!

书接上回,讲到“使用同一个新增弹框”中有未解决的问题,比如复杂的字段,文件,图片上传,这一篇就解决文件上传的问题。这里的场景是在新增弹出框中要上传一个图片,并且这个上传组件放在一个Form中,和其他文本字段一起提交给接口。

这里就有几个要注意的问题:

  1. 图片上传时最好能在前端指定图片类型,根据这个类型上传到指定的目录。比如这里是新增用户,上传用户图片,那么这里就指定类型是“user”,那么就把这个文件上传到服务器的upload/user目录中。这样方便后期维护,比如要把项目中的文件统一迁移到另外一个服务器,只要把upload目录复制出来就好了。
  2. 上传组件是通用的,上传完之后回传给前端一个路径信息,由于使用的是and design中的Form,这时要把这个路径赛到form的数据中一并提交给新增接口。

1.后端上传文件接口

1.1 使用multer

前面在写新增数据,请求数据的时候使用的到中间件bodyParser,解析客户端请求的时候,使用的json类型接受数据,这个很方便,但是上传文件的时候是一般是multipart/form-data这种类型,bodyParser不能解析这种类型。于是这里引入另外一种中间件multer。multer专门处理multipart/form-data类型的表单数据,专业的。

multer有两种使用方式,如果只是一般的网页应用,直接指定dest,也就是上传路径就可以了。如果上传时进行更多的控制,可以使用storage选项。这里我从简单的入手,直接指定文件路径上传一个文件。

// 指定文件上传路径
var upload = multer({dest: path.join(__dirname, './../public/upload/tmp')}); 

这里使用到node.js中的path模块,将./../public/upload/tmp这个相对路径转换成计算机本地路径,注意这里我们在express项目的public目录下新建了upload/tmp目录,至于为啥是tmp这样的临时文件夹,请继续往下看。

接着定义上传接口:

    router.post('/singleFile', upload.single('file'), function (req, res, next) {
    }) 

这里我们定义了一个api/base/singleFile接口,接受Form中一个名叫file的上传文件标签,这样定义之后就可以吧文件上传到public/upload/tmp目录下。

1.2 指定上传目录

multer这种指定路径上传的方式是一开始就指定好了,后面都上传到这个目录,就是说这个目录不能是一个变量,那如何能够根据前端传过来的参数将图片上传到指定的目录呢?我这里首先想到的就是“剪切”文件。既然用的是node.js,文件操作的api就少不了剪切文件了。还有官方文档上说明了,回调函数中除了文件之外,还可以有req.body,如果有文本域数据,将在这个req.body中,这个和bodyParser是类似的。

app.post('/profile', upload.single('avatar'), function (req, res, next) {
  // req.file 是 `avatar` 文件的信息// req.body 将具有文本域数据,如果存在的话
}) 

有了req.file,req.body这两个对象之后剩下的工作就交给node.js了,代码如下:

复制代码

// 文件上传
router.post('/singleFile', upload.single('file'), function (req, res, next) {
  if(req.body.fileLocation) {
    const newName = req.file.path.replace(/\\tmp/, '\\' + req.body.fileLocation) + path.parse(req.file.originalname).ext
    fs.rename(req.file.path, newName, err => {
      if (err) {
        res.json(result.createResult(false, { message: err.message }))
      } else {
        let fileName = newName.split('\\').pop()
        res.json(result.createResult(true, { path: `${req.body.fileLocation}/${fileName}` }))
      }
    })
  } else {
    res.json(result.createResult(false, {message: '未指定文件路径'}))
  }
})

复制代码

注意在这里还使用了fs模块的rename方法,这个方法可以将文件重命名并修改文件路径,就是剪切文件了。这里用replace方法把tmp目录替换成前端传过来的fileLocalhost,然后将文件移动到这个fileLocation目录中。下面使用postman来debug跟踪一下执行过程:

postman请求:

人已赞赏
首页

Python 命令行之旅:使用 click 实现 git 命令

2019-12-19 0:06:19

首页

Google Analytics 的一些用法介绍

2019-12-19 0:21:47

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索