一般情况下,前端的文件上传一般都是通过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中间层实现文件上传

  如果喜欢请关注我的Github,给个Star吧,我会定期分享一些JS中的知识,^_^

node中间层实现文件上传的更多相关文章

  1. node+express实现文件上传功能

    在进行node web开发时,我们可能经常遇到上传文件的问题,这一块如果我们没有经验,可能会遇到很多坑,下面我将跟大家分享一下,实现文件上传的一些方式. 一.node+express文件上传的常用方式 ...

  2. 夺命雷公狗---node.js---11之文件上传

    我们在做文件上传前需要用npm来安装一个插件先, 首先打开项目所在的目录,然后按住shift键然后右键鼠标进入命令行安装formidable 然后开始编写上传的静态页面: <!DOCTYPE h ...

  3. node express formidable 文件上传后修改文件名

    //我是用php的思想来学习nodejs var express = require('express'); var router = express.Router(); var fs = requi ...

  4. Vue+axios+Node+express实现文件上传(用户头像上传)

    Vue 页面的代码 <label for='my_file' class="theme-color"> <mu-icon left value="bac ...

  5. 又拍云 Node.js 实现文件上传、删除

    Node.js 服务端 使用 Node.js + Express.js 实现 服务端 const express = require("express"); const app = ...

  6. ☀【Node】处理文件上传

    Node入门 √http://www.nodebeginner.org/index-zh-cn.html Node.js中所用的fs.renameSync出错:Error: EXDEV, cross- ...

  7. Node.js——获取文件上传进度

    https://juejin.im/post/5a77a46cf265da4e78327552?utm_medium=fe&utm_source=weixinqun

  8. Node.js新手教程——怎样实现文件上传功能

    作者:zhanhailiang 日期:2014-11-16 本文将介绍怎样使用Node.js实现文件上传功能. 1. 初始化项目信息:npm init [root@~/wade/nodejs/node ...

  9. Nodejs学习笔记(八)--- Node.js + Express 实现上传文件功能(felixge/node-formidable)

    目录 前言 formidable简介 创建项目并安装formidable 实现上传功能 运行结果 部分疑惑解析 写在之后 前言 前面讲了一个构建网站的示例,这次在此基础上再说说web的常规功能---- ...

随机推荐

  1. python函数带()与否

    一.不带括号时,调用的是这个函数本身 ,是整个函数体,是一个函数对象,不须等该函数执行完成二.带括号(参数或者无参),调用的是函数的执行结果,须等该函数执行完成的结果 进程和线程的target=fun ...

  2. python基础之 装饰器,内置函数

    1.闭包回顾 在学习装饰器之前,可以先复习一下什么是闭包? 在嵌套函数内部的函数可以使用外部变量(非全局变量)叫做闭包! def wrapper(): money =10 def inner(num) ...

  3. 2019.04.21 python核心特征

    本阶段我们将了解Python是如何管理内存的,学习内存管理让我们掌握python的运行机制: 并且在python中有许多函数式编程的特性,比如闭包,装饰器和生成器,这些都是一些比较难掌握的概念,但面试 ...

  4. MATLAB符号对象与符号运算

    序言 符号对象(Symbolic Objects 不同于普通的数值计算)是Matlab中的一种特殊数据类型,它可以用来表示符号变量.表达式以及矩阵,利用符号对象能够在不考虑符号所对应的具体数值的情况下 ...

  5. 《linux就该这么学》第十三节课:第11章和第12章,vsftpd服务与samba和nfs服务

    第十一章 (借鉴请改动) 11.1.文件传输协议 FTP文件穿数协议,端口20用于数据传输,21端口用于传输相关FTP命令 ftp协议的两种工作模式: 主动模式:ftp向客户端发起 被动模式(默认): ...

  6. HDU 2196树形DP(2个方向)

    HDU 2196 [题目链接]HDU 2196 [题目类型]树形DP(2个方向) &题意: 题意是求树中每个点到所有叶子节点的距离的最大值是多少. &题解: 2次dfs,先把子树的最大 ...

  7. Fiddler抓包【3】_设置断点修改

    1. 断点修改Request 1.1.Request全部中断 设置中断:Rules---> Automatic Breakpoints--->Before Requests 取消中断:Ru ...

  8. 【JavaScript】第8章读书笔记

    本章常用的DOM方法 切记,页面的逻辑是:创建新的元素,给新的元素创建内容,通过appendChild把新元素的内容插入到新元素节点中:通过appendChild把新元素插入到已有元素节点中 书上的老 ...

  9. Git 教程(一):简介和安装

    为什么要编写这个教程?因为我在学习Git的过程中,买过书,也在网上Google了一堆Git相关的文章和教程,但令人失望的是,这些教程不是难得令人发指,就是简单得一笔带过,或者,只支离破碎地介绍Git的 ...

  10. 用 webpack 创建 vue 项目

    1.安装支持webpack 包 npm i -D  webpack webpack-cli  aspnet-webpack webpack-dev-middleware  webpack-hot-mi ...