科普文:Node.js 如何上传文件到后端服务【转】
原文链接 https://www.yuque.com/egg/nodejs/httpclient-upload
背景
互联网时代,无数服务是基于 HTTP 协议进行通信的。
除了常见的 前端浏览器 -> Node 应用 外, Node 应用 -> 后端服务 也是一种非常常见的应用场景。
譬如:
- 调用后端微服务,查询或更新数据。
- 把日志上报给第三方服务。
- 发送文件给后端服务。
Node.js 本身有提供了 http.request() 的能力,但它太底层了,因此社区有 request、superagent 等库。
我们在日常工作中也沉淀出了 urllib 这个基础库,可以使用它来非常便捷地完成任何 HTTP 请求。
request目前已经放弃维护,详见 GitHub 置顶的 2 个 issue:
回到场景,『发送文件给后端服务』是其中一个非常典型的场景,对应于 RFC 1867 规范。
POST https://httpbin.org/post HTTP/1.1
Host: httpbin.org
Content-Length: 495
Content-Type: multipart/form-data; boundary=---------------------------7db2d1bcc50e6e
-----------------------------7db2d1bcc50e6e
Content-Disposition: form-data; name="foo"
bar
-----------------------------7db2d1bcc50e6e
Content-Disposition: form-data; name="upload1"; filename="/tmp/file.md"
Content-Type: text/plain
This is file1.
-----------------------------7db2d1bcc50e6e
Content-Disposition: form-data; name="upload2"; filename="/tmp/file2.md"
Content-Type: text/plain
This is file2, it's longer.
-----------------------------7db2d1bcc50e6e--
然而,对于前端新手来说,有一定的学习门槛,因此,我们提供了一种简化的方式,来减轻新手上手成本。
旧模式
需要自行引入 formstream 这个模块来来帮助我们生成可以被 HttpClient 消费的 form 对象。
const FormStream = require('formstream');
const httpclient = require('urllib');
async function run() {
// 构造对应的 form stream
const form = new FormStream();
form.field('foo', 'bar'); // 设置普通的 headers
form.file('file', __filename); // 添加文件,上传当前文件本身用于测试
// form.file('file2', __filename); // 执行多次来添加多文件
// 发起请求
const url = 'https://httpbin.org/post';
const result = await httpclient.request(url, {
dataType: 'json',
method: 'POST',
// 生成符合 multipart/form-data 要求的请求 headers
headers: form.headers(),
// 以 stream 模式提交
stream: form,
});
console.log(result.data.files);
// 响应最终会是类似以下的结果:
// {
// "file": "'use strict';\n\nconst For...."
// }
}
run().catch(console.error);
新模式
开发者无需自行组装和引入额外模块,仅需提供 files 这个参数即可。
const httpclient = require('urllib');
async function run() {
// 发起请求
const url = 'https://httpbin.org/post';
const result = await httpclient.request(url, {
dataType: 'json',
method: 'POST',
// 设置普通的 headers
data: {
foo: 'bar',
},
// 单文件上传
files: __filename,
// 多文件上传
// files: {
// file1: __filename,
// file2: fs.createReadStream(__filename),
// file3: Buffer.from('mock file content'),
// },
});
console.log(result.data.files);
}
run().catch(console.error);
在 Egg 中使用
Egg 基于 urllib 内置实现了一个 HttpClient,方便应用开发者便捷地发起 HTTP 请求。
注意:本文介绍的是
Node 应用 -> 后端服务之间的文件上传。如果你想了解的是
前端浏览器 -> Node 应用之间的文件上传,请参考对应的文档。
// app/controller/http.js
class HttpController extends Controller {
async upload() {
const { ctx } = this;
const result = await ctx.curl('https://httpbin.org/post', {
method: 'POST',
dataType: 'json',
// 设置普通的 headers
data: {
foo: 'bar',
},
// 单文件上传
files: __filename,
// 多文件上传
// files: {
// file1: __filename,
// file2: fs.createReadStream(__filename),
// file3: Buffer.from('mock file content'),
// },
});
ctx.body = result.data.files;
// 响应最终会是类似以下的结果:
// {
// "file": "'use strict';\n\nconst For...."
// }
}
}
相关资料
- 本文介绍的是
Node 应用 -> 后端服务之间的文件上传,如果你想了解的是前端浏览器 -> Node 应用之间的文件上传,请参考对应的文档。 - 相关文档:httpclient 。
- 对应的 PR 实现:https://github.com/node-modules/urllib/pull/322
科普文:Node.js 如何上传文件到后端服务【转】的更多相关文章
- node.js分片上传文件
前端 : <html> <head> <title>分片上传文件</title> </head> <body> <div ...
- Node.js:上传文件,服务端如何获取文件上传进度
内容概述 multer是常用的Express文件上传中间件.服务端如何获取文件上传的进度,是使用的过程中,很常见的一个问题.在SF上也有同学问了类似问题<nodejs multer有没有查看文件 ...
- Node.js——异步上传文件
前台代码 submit() { var file = this.$refs.fileUpload.files[0]; var formData = new FormData(); formData.a ...
- vue.js异步上传文件前后端代码
上传文件前端代码如下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type&q ...
- 利用ajaxfileupload.js异步上传文件
1.引入ajaxfileupload.js 2.html代码 <input type="file" id="enclosure" name="e ...
- js获取上传文件内容(未完待续)
js 获取上传文件的字节数及内容 <div> 上传文件 : <input type="file" name = "file" id = &qu ...
- Atitit.js获取上传文件全路径
Atitit.js获取上传文件全路径 1. 默认的value只能获取文件名..安全原因.. 1 2. Firefox浏览器的读取 1 3. Html5 的file api 2 4. 解决方法::使用a ...
- js获取上传文件内容
js 获取上传文件的字节数及内容 <div> 上传文件 : <input type="file" name = "file" id = &qu ...
- js能否上传文件夹
文件夹上传:从前端到后端 文件上传是 Web 开发肯定会碰到的问题,而文件夹上传则更加难缠.网上关于文件夹上传的资料多集中在前端,缺少对于后端的关注,然后讲某个后端框架文件上传的文章又不会涉及文件夹. ...
随机推荐
- 查询dba_segmetns 异常慢,在11g 某个库里。
Encountering Slow Performance Reading *_SEGMENTS or *_TS_QUOTAS (文档 ID 1491748.1) 转到底部转到底部 In this D ...
- 如何基于EasyDSS流媒体RTMP、HLS(m3u8)、HTTP-FLV、RTSP服务器体系的全套SDK完成各种场景下的视频应用需求
需求背景 回顾EasyDSS的发展过程,基本上保持的是先局部后系统.先组件后平台的发展方式,一步一步夯实每一个细节功能点,从最基础.最兼容的音视频数据的拉流获取,到高效的.全兼容的数据推流,再到流媒体 ...
- SSO CAS 单点系列
在多系统应用群中,使用,例如,用户账户管理,用户应该有一个统一的账户,不应该让用户在每个子系统分别注册 登陆再分别登出.这就是我们所说的单点登陆问题,即SSO: SSO问题,时大中型web应用经常碰到 ...
- golang高级用法总结
sync.WaitGroup add() done() wait() 相当于计数器,done会减一,wait会等待所有线程都执行完才执行下面代码 sync.pool 用来封装连接池
- jmap使用
今天写的服务在处理大文件是出现Java heap space错误,因此结识了jmap jmap是JDK自带的一个工具,可以做jvm性能调优 可以生成dump文件,查询finalize执行队列.Java ...
- windows下Java调用可执行文件
缘起: 由于没有找到java转换文件的接口,因此使用java调用exe文件进行文件转换 public void convertFile(){ Runtime rn = Runtime.getRunti ...
- 常见的几种异常类型 Exception
常见异常类型:Java中的异常分为两大类: 1.Checked Exception(非Runtime Exception) 2.Unchecked Exception(Runtime Exceptio ...
- Kafka Streams | 流,实时处理和功能
1.目标 在我们之前的Kafka教程中,我们讨论了Kafka中的ZooKeeper.今天,在这个Kafka Streams教程中,我们将学习Kafka中Streams的实际含义.此外,我们将看到Kaf ...
- c++快速排序原理及优化
快速排序 快速排序的时间复杂度为O(logn) 注意:快速排序主要是标志数的选取,如果所选的数恰好为最小或者最大,则是最糟糕的情况,即一轮下来数据没有发生变化! 如何选取中间的标志数成为了算法的关键. ...
- Create your first Java application
参考链接 -[IntelliJ IDEA] https://www.jetbrains.com/help/idea/creating-and-running-your-first-java-appli ...