- 高级 HTTP 请求
- Form 表单提交
- 以 Multipart 方式上传文件
- 以 Stream 方式上传文件
高级 HTTP 请求
在真实的应用场景下,还是会包含一些较为复杂的 HTTP 请求。
Form 表单提交
面向浏览器设计的 Form 表单(不包含文件)提交接口,通常都要求以 content-type: application/x-www-form-urlencoded的格式提交请求数据。
// app/controller/npm.jsclass NpmController extends Controller {async submit() {const ctx = this.ctx;const result = await ctx.curl('https://httpbin.org/post', {// 必须指定 method,支持 POST,PUT 和 DELETEmethod: 'POST',// 不需要设置 contentType,HttpClient 会默认以 application/x-www-form-urlencoded 格式发送请求data: {now: Date.now(),foo: 'bar',},// 明确告诉 HttpClient 以 JSON 格式处理响应 bodydataType: 'json',});ctx.body = result.data.form;// 响应最终会是类似以下的结果:// {// "foo": "bar",// "now": "1483864184348"// }}}
以 Multipart 方式上传文件
当一个 Form 表单提交包含文件的时候,请求数据格式就必须以 multipart/form-data进行提交了。
[urllib] 内置了 [formstream] 模块来帮助我们生成可以被消费的 form 对象。
// app/controller/http.jsclass HttpController extends Controller {async upload() {const { ctx } = this;const result = await ctx.curl('https://httpbin.org/post', {method: 'POST',dataType: 'json',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...."// }}}
以 Stream 方式上传文件
其实,在 Node.js 的世界里面,Stream 才是主流。如果服务端支持流式上传,最友好的方式还是直接发送 Stream。Stream 实际会以 Transfer-Encoding: chunked 传输编码格式发送,这个转换是 [HTTP] 模块自动实现的。
// app/controller/npm.jsconst fs = require('fs');const FormStream = require('formstream');class NpmController extends Controller {async uploadByStream() {const ctx = this.ctx;// 上传当前文件本身用于测试const fileStream = fs.createReadStream(__filename);// httpbin.org 不支持 stream 模式,使用本地 stream 接口代替const url = `${ctx.protocol}://${ctx.host}/stream`;const result = await ctx.curl(url, {// 必须指定 method,支持 POST,PUTmethod: 'POST',// 以 stream 模式提交stream: fileStream,});ctx.status = result.status;ctx.set(result.headers);ctx.body = result.data;// 响应最终会是类似以下的结果:// {"streamSize":574}}}
