rfc2388表单上传文件NodeJS无依赖版本实现
文章目录
上传媒体文件API的是基于 RFC2388 协议,圈定的范围是,有大小限制的图片(2M)或者视频(5M)类型单文件,按API接口标准,需要对文件的meta{filename,sha256}信息做数据签名,并且这个meta还须随请求载核一同发送给服务端,难就难在这里了,唉嘘~
官方文档小分队犯了一个错误,就是试图用文本语言来表达非字符内容,整得一众开发者迷途了,社区反馈波澜滔滔。这支小分队应该每人扣一个长鹅抱宠,捐给像俺这样努力帮扶开发者的贡献者(😄)。其实rfc2388标准上有写,这个协议就是扩展HTTP文本协议,用来传输非字符内容的,引述如下:
multipart/form-data can be used for forms that are presented using representations other than HTML (spreadsheets, Portable Document Format, etc), and for transport using other means than electronic mail or HTTP. This document defines the representation of form values independently of the application for which it is used.
上述引述内容,提到3种文件,HTML文件还算是字符型文件,表格及PDF文件就已经算是二进制文件了,文件内容人类得借助专用软件翻译,才能转成可被识别内容(肉眼能直接识别的是大牛,不再此列)。受官方技术助手伙伴在某次问答亲测有效代码截图启示,特意又研读了几遍RFC协议,国庆档给抽出成无依赖ES2015版本,已内置于另一款著名支付产品SDK包中,亲测可用,以下版本是微信支付社区特供,单文件、无依赖,适合云开发集成使用。
废话说了一箩筐,还是上代码吧:
|
|
测试用例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
lib/form ✓ should be class `Form` new Form ✓ should instanceOf Form and have properties `data` and `indices` ✓ The `mimeTypes` property should be there and only allowed append(cannot deleted) ✓ The `dashDash` Buffer property should be there and cannot be deleted/modified ✓ The `boundary` Buffer property should be there and cannot be deleted/modified ✓ The `CRLF` Buffer property should be there and cannot be deleted/modified ✓ The `data` property should be instanceOf Array and cannot deleted ✓ The `indices` property should be instanceOf Object and cannot deleted ✓ Method `getBuffer()` should returns a Buffer instance and had fixed length(108) default ✓ Method `getHeaders()` should returns a Object[`Content-type`] with `multipart/form-data; boundary=` ✓ Method `appendMimeTypes()` should returns the Form instance ✓ Method `appendMimeTypes({any: 'mock'})` should returns the Form instance, and affected `form.data` property ✓ Method `append()` should returns the Form instance, and affected `form.data` property ✓ Method `append()` should append name="undefined" disposition onto the `form.data` property ✓ Method `append({}, 1)` should append name="[object Object]" disposition onto the `form.data` property ✓ Method `append('meta', JSON.stringify({}), 'meta.json')` should append a `Content-Type: application/json` onto the `form.data` property ✓ Method `append('image_content', Buffer.from('R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==', 'base64'), 'demo.gif')` should append a `Content-Type: image/gif` onto the `form.data` property |
API文档如下
Simple and lite of multipart/form-data
implementation, most similar to form-data
|
|
-
- new Form()
- .getBuffer() ⇒
Buffer
- .getHeaders() ⇒
Object.<string, string>
- .appendMimeTypes(things) ⇒
Form
- .append(field, value, [filename]) ⇒
Form
new Form()
- Create a
multipart/form-data
buffer container for the file uploading.
- Create a
form.getBuffer() ⇒
Buffer
- To retrieve the
data
buffer - Kind: instance method of
Form
- Returns:
Buffer
- - The payload buffer
- To retrieve the
form.getHeaders() ⇒
Object.<string, string>
- To retrieve the
Content-Type
multipart/form-data header - Kind: instance method of
Form
- Returns:
Object.<string, string>
- - TheContent-Type
header Withthis.boundary
- To retrieve the
form.appendMimeTypes(things) ⇒
Form
form.append(field, value, [filename]) ⇒
Form
- Append data wrapped by
boundary
- Kind: instance method of
Form
- Returns:
Form
- - TheForm
class instance self - Param: field
- Type:
string
- Description: The field
- Param: value
- Type:
string
|Buffer
- Description: The value
- Param: [filename]
- Type:
string
|Buffer
- Description: Optional filename, when provided, then append the
Content-Type
after of theContent-Disposition
- Append data wrapped by
mimeTypes :
Object.<string, string>
- built-in mime-type mapping
- Kind: global variable
dashDash :
Buffer
- Kind: global variable
boundary :
Buffer
- Kind: global variable
CRLF :
Buffer
- Kind: global variable
data :
array.<Buffer>
- The Form’s data storage
- Kind: global variable
indices :
Object.<string, number>
- The entities’ value indices whose were in
this.data
- The entities’ value indices whose were in
此类内置常用的几种文件类型(append
第三入参以文件名后缀比对),已经够用了,视频仅内置了两种,对于 官方接口支持的avi
, wmv
, mov
, mkv
, flv
, f4v
, m4v
, rmvb
,开发者可用透过 appendMimeTypes
方法,自行扩展以符合 RFC2388 规范。
图片上传接口,用法
|
|
整个需要发送的表单体就准备妥当了,然后按照v3开发规范,该数据签名的签名,想用什么client
提交就用什么client
,然后就没然后了。。。
以我习惯用的 axios
为例,数据提交类似如下:
|
|
写到最后
Form类文件以MIT开源,文章转载请注明出处「来自微信开发者社区」。
文章作者 James
上次更新 2021-02-28