首发掘金 记录一次node中台转发表单上传文件到后台过程 本篇跟掘金为同一个作者leung
 
公司几个项目都是三层架构模式即前台,中台(中间层),后台。前台微信端公众号使用vue框架,后台管理前端使用react,中台(中间层)使用node,后台使用java。此次说的是后台关键上传数据文件时遇到的一个bug,因为是三层架构,前台表单会先提交到node中间层,然后再通过node中间层转发到java后台保存并读取文件数据。 此次遇到了一个bug当表单提交到node中间层的时候node接口request可以获取得到表单上传的文件信息,就在node端创建http请求转发到后台的时候后台报错了:the request was rejected because no multipart boundary was found后台收到的接口请求中得不到boundary信息,此时已确定node创建的http请求中headers中Content-Type为multipart/form-data,很显然java后台没收到上传文件信息,通过在页面创建form表单使用后台上传接口地址发现后台可以上传,这证明后台接口没问题,node中台接口也能收到form表单上传文件数据,那么范围进一步缩小问题就出现在node http请求转发到后台这步的问题了。既然后台接口请求体中没有boundary那么问题就出现在创建请求的时候少给了东西后台了,Google+百度了一下找到的解决方式在发现都不行,不能说完全没有用但是还是找到了方向。后台要的是表单数据,那node中台转发的时候就转发一个表单数据。于是找到了form-data这个包及connect-multiparty中间件。 先插入一段代码然后再分析;

node-fetch方式发送请求到后台

 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('/uploadFile', multipartMiddleware, (req, res) => {
const { path: filePath, originalFilename } = req.files.file
const newPath = path.join(path.dirname(filePath), originalFilename) // 得到newPath新地址用于创建读取流
fs.rename(filePath, newPath, (err) => {
if (err) {
return;
} else {
const file = fs.createReadStream(newPath) //创建读取流
const form = new FormData() // new formdata实例
form.append('file', file) // 把文件加入到formdata实例中
fetch('后台接口上传地址like:https://ip:端口/接口', {
method: "POST",
body: form,
headers: form.getHeaders() // 这步非常重要一定要把formdata的headers放在请求体headers中我发现网上很多例子讲的都没这个headers,没有这个后台还是会报boundary的错因为boundary是在request headers中
}).then(res => res.json()).then(data => {
res.send({data: data}) //将上传结果返回给前端
})
}
})
});
这种方式没有使用node http请求使用到了fetch,只是一种请求方式,换成axios其实也是一样的,最主要的是发送请求的时候除了往formdata中append file文件信息外,headers一定要是formdata的headers不然后台还是接收不到request中的boundary。

node http方式发送请求到后台

 const fs = require('fs')
const path = require('path')
const FormData = require('form-data')
const express = require('express')
var http = require('http');
const router = express.Router()
const multipart = require('connect-multiparty');
var multipartMiddleware = multipart()
router.post('/uploadFile', multipartMiddleware, (req, res) => {
const { path: filePath, originalFilename } = req.files.file
const newPath = path.join(path.dirname(filePath), originalFilename) // 得到newPath新地址用于创建读取流
fs.rename(filePath, newPath, (err) => {
if (err) {
return;
} else {
const file = fs.createReadStream(newPath) //创建读取流
const form = new FormData() // new formdata实例
form.append('file', file) // 把文件加入到formdata实例中
var request = http.request({
method: 'post',
host: 'http://ip:port',
path: '/xxxx', //上传接口
headers: form.getHeaders() //formdata的headers
});
form.pipe(request);
request.on('response', (response) => {
res.send({data: response})
});
}
})
})

这种方式使用的是node中http方式,相关注意事项其实跟node-fetch差不多只是发送的差别而已。

其实项目中我们是把请求方式http单独抽取到一个文件中的这样方便管理,这里只是为了方便说明情况把它放到node中台接口中。其实不管是哪种方式都是换汤不换药的都是将append后formdata中的文件信息同时还有formdata headers发送到后台接口就可以了。

今天周末有时间总结一下,最后如果有不对的地方希望大家指正一起学习,谢谢!

首发掘金 记录一次node中台转发表单上传文件到后台过程 本篇跟掘金为同一个作者leung

记录一次node中台转发表单上传文件到后台过程的更多相关文章

  1. 通过form表单上传文件获取后台传来的数据

    小伙伴是不是遇到过这样的问题,通过submit提交form表单的时候,不知怎么获取后台传来的返回值.有的小伙伴就会说你不会发送ajax,其实也会.假如提交的form表单中含有文件,怎么办? 步骤1:想 ...

  2. django 基于form表单上传文件和基于ajax上传文件

    一.基于form表单上传文件 1.html里是有一个input type="file" 和 ‘submit’的标签 2.vies.py def fileupload(request ...

  3. java模拟表单上传文件,java通过模拟post方式提交表单实现图片上传功能实例

    java模拟表单上传文件,java通过模拟post方式提交表单实现图片上传功能实例HttpClient 测试类,提供get post方法实例 package com.zdz.httpclient; i ...

  4. ASP.NET MVC中使用表单上传文件时的注意事项

    最近了好久没写ASP.NET 使用HTML的FORM来上传文件了,结果写了个文件上传发现ASP.NET MVC的Controller中老是读取不到上传的文件. MVC的View(Index.cshtm ...

  5. Express下使用formidable实现POST表单上传文件并保存

    Express下使用formidable实现POST表单上传文件并保存 在上一篇文章中使用formidable实现了上传文件,但没将它保存下来. 一开始,我也以为是只得到了文件的相关信息,需要用fs. ...

  6. 巨蟒python全栈开发django11:ajax&&form表单上传文件contentType

    回顾: 什么是异步? 可以开出一个线程,我发出请求,不用等待返回,可以做其他事情. 什么是同步? 同步就是,我发送出了一个请求,需要等待返回给我信息,我才可以操作其他事情. 局部刷新是什么? 通过jq ...

  7. vue form表单上传文件

    <script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js">< ...

  8. 使用form表单上传文件

    在使用form表单上传文件时候,input[type='file']是必然会用的,其中有一些小坑需要避免. 1.form的 enctype="multipart/form-data" ...

  9. from 表单上传文件和下载?

    from表单上传单个文件的方法. 分为三个部分,简单演示. 一部分 表单上传文件 <%-- Created by IntelliJ IDEA. User: Administrator Date: ...

随机推荐

  1. CAD使用GetAllAppName读所有名称(com接口)

    主要用到函数说明: MxDrawEntity::GetAllAppName 得到所有扩展数据名称,详细说明如下: 参数 说明 [out, retval] IMxDrawResbuf** ppRet 返 ...

  2. 递归删除N天前的文件夹及子文件夹下的特定文件

    @echo offrem 设置被删除文件夹路径set SrcDir=D:\tmp\test\rem 设置文件保存天数set Days=2rem /p指定搜索文件的路径 /s 在子目录中搜索 /m 指定 ...

  3. 字符串匹配算法之BM算法

    BM算法,全称是Boyer-Moore算法,1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了一种新的字符串匹配算法. BM算法定义了两个规则: ...

  4. <Linux> 下安装和卸载JDK

    安装 下载jdk https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 在local ...

  5. mybatis中<![CDATA[]]>的作用

    此篇文章引自QH_JAVA的文章 在使用mybatis 时我们sql是写在xml 映射文件中,如果写的sql中有一些特殊的字符的话,在解析xml文件的时候会被转义,但我们不希望他被转义,所以我们要使用 ...

  6. Python之粘包

    Python之粘包 让我们基于tcp先制作一个远程执行命令的程序(1:执行错误命令 2:执行ls 3:执行ifconfig) 注意注意注意: res=subprocess.Popen(cmd.deco ...

  7. MongoDB数据库的安装

    首先就是MongoDB的下载,可以去MongoDB官网进行下载,https://www.mongodb.com/download-center/community,也可以通过百度网盘直接下载, 链接: ...

  8. 2017 计蒜之道 初赛 第一场 A 阿里的新游戏

    题链:https://nanti.jisuanke.com/t/15499 这题观察图纸可知成三线段上的相邻点之间的距离有1,2,3三种情况的,同时要成线段必然是同横坐标或者纵坐标,然后我们排除掉穿过 ...

  9. cogs1752[boi2007]mokia 摩基亚 (cdq分治)

    [题目描述] 摩尔瓦多的移动电话公司摩基亚(Mokia)设计出了一种新的用户定位系统.和其他的定位系统一样,它能够迅速回答任何形如“用户C的位置在哪?”的问题,精确到毫米.但其真正高科技之处在于,它能 ...

  10. 竞赛Noi_Linux使用总结(vim)

    刚换完Linux,趁着教练给的改题时间(T2确实猛)自己上网找了好多博客,发现很多跟竞赛有关的内容是碎片化的,从最基本的如何用vim写代码.编译.运行,再到怎么改设置使打代码时手感强一些,最后学对拍, ...