Skip to content

Commit

Permalink
docs: httpclient upload files (eggjs#3682)
Browse files Browse the repository at this point in the history
  • Loading branch information
atian25 authored May 7, 2019
1 parent da2d439 commit 17fab1c
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 47 deletions.
73 changes: 49 additions & 24 deletions docs/source/en/core/httpclient.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,46 +197,41 @@ class NpmController extends Controller {
### Uploading Files by Multipart

Once form submission contains files, submission of requesting data must be [multipart/form-data](http://tools.ietf.org/html/rfc2388)
We need to introduce third party module [formstream] to generate `form` objects that can be consumed by HttpClient.
[urllib] has a built-in module [formstream] to generate `form` objects that can be consumed by HttpClient.

```js
// app/controller/npm.js
const FormStream = require('formstream');
class NpmController extends Controller {
// app/controller/http.js
class HttpController extends Controller {
async upload() {
const ctx = this.ctx;
const form = new FormStream();
// set normal field and value
form.field('foo', 'bar');
// uploading the current file for test propose
form.file('file', __filename);
const { ctx } = this;

const result = await ctx.curl('https://httpbin.org/post', {
// method is required, supports POST,PUT
method: 'POST',
// generate request headers following the requirements of multipart/form-data
headers: form.headers(),
// submitted as stream mode
stream: form,
// telling HttpClient to process the return body as JSON format explicitly
dataType: 'json',
data: {
foo: 'bar',
},

// one file
files: __filename,

// many files
// files: {
// file1: __filename,
// file2: fs.createReadStream(__filename),
// file3: Buffer.from('mock file content'),
// },
});

ctx.body = result.data.files;
// final response will similar as below:
// Response:
// {
// "file": "'use strict';\n\nconst For...."
// }
}
}
```

Of course, you can add more files to achieve the requirements of upload multiple files at one time by `form.file()`

```js
form.file('file1', file1);
form.file('file2', file2);
```

### Uploading Files in Stream Mode

In fact, Stream is the leading in the world of Node.js.
Expand Down Expand Up @@ -383,6 +378,36 @@ ctx.curl(url, {
});
```

### `files: Mixed`

File upload, support: `String | ReadStream | Buffer | Array | Object`.

```js
ctx.curl(url, {
method: 'POST',
files: '/path/to/read',
data: {
foo: 'other fields',
},
});
```

upload multiple files:

```js
ctx.curl(url, {
method: 'POST',
files: {
file1: '/path/to/read',
file2: fs.createReadStream(__filename),
file3: Buffer.from('mock file content'),
},
data: {
foo: 'other fields',
},
});
```

### `stream: ReadStream`

Set request context's readable stream, default `null`.
Expand Down
72 changes: 49 additions & 23 deletions docs/source/zh-cn/core/httpclient.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,30 +201,33 @@ class NpmController extends Controller {

当一个 Form 表单提交包含文件的时候,请求数据格式就必须以 [multipart/form-data](http://tools.ietf.org/html/rfc2388)
进行提交了。
这个时候需要引入 [formstream] 这个第三方模块来帮助我们生成可以被 HttpClient 消费的 `form` 对象。

[urllib] 内置了 [formstream] 模块来帮助我们生成可以被消费的 `form` 对象。

```js
// app/controller/npm.js
const FormStream = require('formstream');
class NpmController extends Controller {
// app/controller/http.js
class HttpController extends Controller {
async upload() {
const ctx = this.ctx;
const form = new FormStream();
// 设置普通的 key value
form.field('foo', 'bar');
// 上传当前文件本身用于测试
form.file('file', __filename);
const { ctx } = this;

const result = await ctx.curl('https://httpbin.org/post', {
// 必须指定 method,支持 POST,PUT
method: 'POST',
// 生成符合 multipart/form-data 要求的请求 headers
headers: form.headers(),
// 以 stream 模式提交
stream: form,
// 明确告诉 HttpClient 以 JSON 格式处理响应 body
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;
// 响应最终会是类似以下的结果:
// {
Expand All @@ -234,13 +237,6 @@ class NpmController extends Controller {
}
```

当然,你还可以继续通过 `form.file()` 添加更多文件以实现一次性上传多个文件的需求。

```js
form.file('file1', file1);
form.file('file2', file2);
```

### 以 Stream 方式上传文件

其实,在 Node.js 的世界里面,Stream 才是主流。
Expand Down Expand Up @@ -390,6 +386,36 @@ ctx.curl(url, {
});
```

### `files: Mixed`

文件上传,支持格式: `String | ReadStream | Buffer | Array | Object`

```js
ctx.curl(url, {
method: 'POST',
files: '/path/to/read',
data: {
foo: 'other fields',
},
});
```

多文件上传:

```js
ctx.curl(url, {
method: 'POST',
files: {
file1: '/path/to/read',
file2: fs.createReadStream(__filename),
file3: Buffer.from('mock file content'),
},
data: {
foo: 'other fields',
},
});
```

### `stream: ReadStream`

设置发送请求正文的可读数据流,默认是 `null`
Expand Down
4 changes: 4 additions & 0 deletions lib/core/messenger/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
const LocalMessenger = require('./local');
const IPCMessenger = require('./ipc');

/**
* @class Messenger
*/

exports.create = egg => {
return egg.options.mode === 'single'
? new LocalMessenger(egg)
Expand Down

0 comments on commit 17fab1c

Please sign in to comment.