node中间层实现文件上传功能


Posted in Javascript onJune 11, 2018

一般情况下,前端的文件上传一般都是通过form表单的(<input type="file" />)来完成文件的上传,如果使用node中间层完成跨域,文件的上传就需要在node中间层处理成可读流,转成formData完成转发。

一、form表单文件上传

这是最常见的文件上传方式,通过form表单实现,简单实用,设置一下method、enctype、action属性就可以了,多文件上传需要设置multiple属性(部分浏览器支持还是有些问题的)。

<form method="post" enctype="multipart/form-data" action="/api/upload">
  <input type="text" name="username">
  <input type="password" name="password">
  <input type="file" name="file">
  <input type="submit">
</form>

二、FormData实现文件上传

FormData对象用以将数据编译成键值对,以便向后台发送数据。其主要用于发送表单数据,但亦可用于发送带键数据(keyed data),而独立于表单使用。对部分浏览器对multiple属性不支持的情况,可以使用formData的提交方式完成。

<!-- 获取上传文件转成formData类型的文件 -->
<input multiple id="file" name="file" type="file" />
<button id="btn">提交</button>

const oFile = document.getElementById('file')
const oBtn = document.getElementById('btn')

oBtn.addEventListener('click', () => {
  files = oFile.files
  const formData = new FormData()
  formData.append('file', files[0])
  formData.append('file1', files[1])

  fetch('/api/upload', {
    method: "POST",
    body: formData
  })
})

使用fetch请求不要设置Content-Type,否则无法请求

fetch请求默认是不带cookie 

三、node中间层完成文件上传跨域

跨域是因为浏览器的同源策略造成,跨域的方法有很多中,这里使用的是node中间层代理完成(服务端之间的请求是不存在跨域问题)。

node无法直接解析上传的文件,需要引入拓展包connect-multiparty完成,这样就可以拿到文件数据。

拿到上传文件,需要在node中转发请求后台server,这里的文件不能直接发给后台,需要将上传的文件使用fs.createReadStream转成可读流,同时引入 form-data 包(node环境是没有formData对象的),这样就可以实现node中间层转发文件类型

node部分代码:

const fs = require('fs')
const path = require('path')
const FormData = require('form-data')
const express = require('express')
const fetch = require('node-fetch')
const router = express.Router()
const multipart = require('connect-multiparty');
var multipartMiddleware = multipart()

router.post('/upload', multipartMiddleware, function (req, res) {
  // console.log(req.body, req.files);

  const { path: filePath, originalFilename } = req.files.file
  const newPath = path.join(path.dirname(filePath), originalFilename)

  fs.rename(filePath, newPath, function (err) {
    if (err) {
      return;
    }
    else {
      const file = fs.createReadStream(newPath)
      const form = new FormData()
      form.append('file', file)

      fetch('http://localhost:8080/upload', {
        method: "POST",
        body: form
      })
    }
  })
  res.json({})
});

module.exports = router;

注意:

  • node无法直接解析上传文件,需要引入npm包connect-multiparty中间件,或者引入npm包multiparty
  • node拿到文件,需要使用fs.createReadStream转成可读流
  • node环境没有formData对象,需要引入npm包form-data
  • fetch请求提交formData数据,不能设置Comtemt-Type

最后给大家附上完整的代码: node中间层实现文件上传

总结

以上所述是小编给大家介绍的node中间层实现文件上传功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
通用于ie和firefox的函数 GetCurrentStyle (obj, prop)
Dec 27 Javascript
使用jQuery的将桌面应用程序引入浏览器
Nov 19 Javascript
原生JavaScript实现连连看游戏(附源码)
Nov 05 Javascript
jqGrid日期格式的判断示例代码(开始日期与结束日期)
Nov 08 Javascript
javascript函数中参数传递问题示例探讨
Jul 31 Javascript
JS实现进入页面时渐变背景色的方法
Feb 25 Javascript
JQuery实现可直接编辑的表格
Apr 16 Javascript
基于javascript数组实现图片轮播
May 02 Javascript
基于BootStrap Metronic开发框架经验小结【七】数据的导入、导出及附件的查看处理
May 12 Javascript
原生js封装的一些jquery方法(详解)
Sep 20 Javascript
使用node.js搭建服务器
May 20 Javascript
Vue分页效果与购物车功能
Dec 13 Javascript
几个你不知道的技巧助你写出更优雅的vue.js代码
Jun 11 #Javascript
Vue.js 中取得后台原生HTML字符串 原样显示问题的解决方法
Jun 10 #Javascript
实例详解Node.js 函数
Jun 10 #Javascript
微信小程序实现倒计时调用相机自动拍照功能
Jun 10 #Javascript
深入浅析Vue中的Prop
Jun 10 #Javascript
vue项目部署上线遇到的问题及解决方法
Jun 10 #Javascript
js技巧之十几行的代码实现vue.watch代码
Jun 09 #Javascript
You might like
php结合ajax实现赞、顶、踩功能实例
2014/05/12 PHP
尽可能写&quot;友好&quot;的&quot;Javascript&quot;代码
2007/01/09 Javascript
Jquery 的扩展方法总结
2011/10/01 Javascript
浅析jQuery中调用ajax方法时在不同浏览器中遇到的问题
2014/06/11 Javascript
jQuery不兼容input的change事件问题解决过程
2014/12/05 Javascript
jquery中添加属性和删除属性
2015/06/03 Javascript
JavaScript操作XML/HTML比较常用的对象属性集锦
2015/10/30 Javascript
javascript实现别踩白块儿小游戏程序
2015/11/22 Javascript
JavaScript之生成器_动力节点Java学院整理
2017/06/30 Javascript
protractor的安装与基本使用教程
2017/07/07 Javascript
JQuery元素快速查找与操作
2018/04/22 jQuery
js实现指定时间倒计时效果
2019/08/26 Javascript
记一次vue跨域的解决
2020/10/21 Javascript
Javascript数组及类数组相关原理详解
2020/10/29 Javascript
[01:01:35]Optic vs paiN 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
python从入门到精通(DAY 1)
2015/12/20 Python
Python3.2模拟实现webqq登录
2016/02/15 Python
python+selenium开发环境搭建图文教程
2017/08/11 Python
Python温度转换实例分析
2018/01/17 Python
python之django母板页面的使用
2018/07/03 Python
Django REST framework内置路由用法
2019/07/26 Python
Python scrapy增量爬取实例及实现过程解析
2019/12/24 Python
Python 实现训练集、测试集随机划分
2020/01/08 Python
解决pytorch报错:AssertionError: Invalid device id的问题
2020/01/10 Python
selenium携带cookies模拟登陆CSDN的实现
2021/01/19 Python
深入理解Python变量的数据类型和存储
2021/02/01 Python
Html5 Canvas 实现一个“刮刮乐”游戏
2019/09/05 HTML / CSS
一套C#面试题
2013/10/09 面试题
2016公司年会通知范文
2015/04/25 职场文书
公司老总年会致辞
2015/07/30 职场文书
高中物理教学反思
2016/02/19 职场文书
《悬崖边的树》读后感2篇
2019/12/02 职场文书
Vue3 Composition API的使用简介
2021/03/29 Vue.js
Python - 10行代码集2000张美女图
2021/05/23 Python
OpenCV全景图像拼接的实现示例
2021/06/05 Python
SpringBoot集成Druid连接池连接MySQL8.0.11
2021/07/02 Java/Android