如何在函数计算中使用 Node.js 处理 multipart 文件上传请求

本文涉及的产品
简介: web 开发中我们经常会允许用户通过 HTTP POST 请求上传文档到服务器,本文将介绍在函数计算中基于 node.js 使用 multipart form-data 来实现文件上传服务。

前言

web 开发中我们经常会允许用户通过 HTTP POST 请求上传文档到服务器,如何使用函数计算来做文件上传服务呢?下面我们使用 nodejs 来实现一个文件上传的案例:

我们知道浏览器中上传文档通常会使用 multipart form-data 来多文件同时上传文件。

例如,我们可以使用curl来做这个测试模拟上传两个文件: test.txtindex.js

curl -v --request POST --header "Content-Type:multipart/form-data" --form upload=@"test.txt" --form upload=@"index.js" https://example.com/upload/

格式分析

为了实现这个上传服务,我们先来了解一下 multipart 的 HTTP header 及 body 格式:

为了简单起见,我们使用一个文件内容为 111111\n 的文本文件 test.txt
通过上述指令,我们可以看到 request 的 header 部分,会多出一个类似下述的 header:

Content-Type:multipart/form-data; boundary=------------------------7b433b8e13cbec1c

而 POST body 则大致如下:

"--------------------------7b433b8e13cbec1c\r\nContent-Disposition: form-data; name=\"upload\"; filename=\"test.txt\"\r\nContent-Type: text/plain\r\n\r\n111111\n\r\n--------------------------7b433b8e13cbec1c--\r\n"

我们可以认为 body 被分成了多个片,每个片使用 header 中的 boundary 来做前后分隔,中间的内容则包含了这个分片的各种属性。

实现

安装第三方库

接下来,我们使用一个三方 parser 库 parse-multipart 来解析 POST body 的数据。

npm install parse-multipart

函数实现示例

我们在代码目录新增 index.js 粘贴以下内容:

// curl -v --request POST --header "Content-Type:multipart/form-data" --form upload=@"test.txt" https://<your-endpoint>/2016-08-15/proxy/test_service/file-upload/
var getRawBody = require('raw-body');

// see https://www.npmjs.com/package/parse-multipart
// npm install parse-multipart
var multipart = require('parse-multipart');

// regexp to parse boundary from HTTP header
var RE_BOUNDARY = /^multipart\/.+?(?:; boundary=(?:(?:"(.+)")|(?:([^\s]+))))$/i

module.exports.handler = function(req, resp, context) {
    console.log('file upload');

    var params = {
        path: req.path,
        queries: req.queries,
        headers: req.headers,
        method : req.method,
        requestURI : req.url,
        clientIP : req.clientIP,
    }
    getRawBody(req, function(err, body) {
        for (var key in req.queries) {
          var value = req.queries[key];
          resp.setHeader(key, value);
        }
        params.body = body.toString();
        var m = RE_BOUNDARY.exec(req.headers['content-type'])
        var boundary = m[1] || m[2]
        params.boundary = boundary
        var parts = multipart.Parse(body, boundary);
        params.parts = parts
        resp.send(JSON.stringify(params, null, '    '));
    });
}

创建函数后,我们可以为这个函数创建 HTTP trigger,并为选择 POST 作为可接受 HTTP Method。

测试

创建完成后,我们可以使用上面的 curl 命令来做测试:

curl -v --request POST --header "Content-Type:multipart/form-data" --form upload=@"test.txt" https://<endpoint>/2016-08-15/proxy/test_service/file-upload/

测试结果大致如下:

* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: *.fc.aliyuncs.com
* Server certificate: GlobalSign Organization Validation CA - SHA256 - G2
* Server certificate: GlobalSign Root CA
> POST /2016-08-15/proxy/test_service/file-upload/ HTTP/1.1
> Host: ************.cn-shanghai.fc.aliyuncs.com
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Length: 195
> Expect: 100-continue
> Content-Type:multipart/form-data; boundary=------------------------7b433b8e13cbec1c
>
< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< Access-Control-Expose-Headers: Date,x-fc-request-id,x-fc-error-type,x-fc-code-checksum,x-fc-invocation-duration,x-fc-max-memory-usage,x-fc-log-result,x-fc-invocation-code-version
< Content-Disposition: attachment
< Content-Length: 1089
< Content-Type: application/octet-stream
< X-Fc-Code-Checksum: 8133380019009032134
< X-Fc-Invocation-Duration: 4
< X-Fc-Invocation-Service-Version: LATEST
< X-Fc-Max-Memory-Usage: 17.31
< X-Fc-Request-Id: b227b724-b14b-6413-22be-c868b395c732
< Date: Tue, 04 Jun 2019 03:41:04 GMT
<
{
    "path": "/",
    "queries": {},
    "headers": {
        "accept": "*/*",
        "content-length": "195",
        "content-type": "multipart/form-data; boundary=------------------------7b433b8e13cbec1c",
        "expect": "100-continue",
        "user-agent": "curl/7.54.0"
    },
    "method": "POST",
    "requestURI": "/2016-08-15/proxy/test_service/file-upload/",
    "clientIP": "123.123.123.123",
    "body": "--------------------------7b433b8e13cbec1c\r\nContent-Disposition: form-data; name=\"upload\"; filename=\"test.txt\"\r\nContent-Type: text/plain\r\n\r\n111111\n\r\n--------------------------7b433b8e13cbec1c--\r\n",
    "boundary": "------------------------7b433b8e13cbec1c",
    "parts": [
        {
            "filename": "test.txt",
            "type": "text/plain",
            "data": {
                "type": "Buffer",
                "data": [
                    49,
                    49,
                    49,
                    49,
                    49,
                    49,
                    10
                ]
            }
        }
    ]
}

我们可以看到 parts 数组中的数据,其中 data 为一个 Buffer 字节数组[49, 49, 49, 49, 49, 49, 10],转成 string"111111\n"

使用限制

由于目前函数计算对于调用请求有最多 6MB 的大小限制,如果上传需要处理大文件,请先上传到 OSS bucket,然后再通过函数计算来处理相关请求。

更多参考

相关实践学习
基于函数计算一键部署掌上游戏机
本场景介绍如何使用阿里云计算服务命令快速搭建一个掌上游戏机。
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
目录
相关文章
|
移动开发 Serverless
如何在函数计算中使用 Node.js 处理 multipart 文件上传请求
## 前言 web 开发中我们经常会允许用户通过 HTTP POST 请求上传文档到服务器,如何使用函数计算来做文件上传服务呢?下面我们使用 nodejs 来实现一个文件上传的案例: 我们知道浏览器中上传文档通常会使用 `multipart` `form-data` 来多文件同时上传文件。 例如,我们可以使用curl来做这个测试模拟上传两个文件: `test.txt` 和 `inde
2108 0
|
14天前
|
JSON JavaScript 前端开发
❤Nodejs 第九章(token身份认证和express-jwt的安装认识)
【4月更文挑战第9天】Node.js第九章介绍了Token身份认证,特别是JWT(JSON Web Token)作为跨域认证的解决方案。JWT由Header、Payload和Signature三部分组成,用于在客户端和服务器间安全传输用户信息。前端收到JWT后存储在localStorage或sessionStorage中,并在请求头中发送。Express-JWT是一个中间件,用于解析JWT。基本用法包括设置secret和algorithms。注意安全问题,避免混合使用不同算法以防止降级攻击。
36 0
|
1月前
|
JavaScript Windows
Win7内网安装高版本的Node方法,亲测有效node-v16.16.0
Win7内网安装高版本的Node方法,亲测有效node-v16.16.0
38 0
|
2月前
|
JavaScript Linux 数据安全/隐私保护
node内网安装npm私服以及依赖包上传发布verdaccio
node内网安装npm私服以及依赖包上传发布verdaccio
79 1
|
7天前
|
JavaScript 前端开发 Linux
Node.js安装与配置
`Node.js` 是一个基于 `Chrome V8` 引擎的 `JavaScript` 运行环境,它允许开发者使用 `JavaScript` 编写服务器端代码。以下是 `Node.js` 的安装与配置的详细步骤:
Node.js安装与配置
|
7天前
|
JSON JavaScript 关系型数据库
❤Nodejs 第十六章(Nodejs环境安装和依赖使用)
【4月更文挑战第16天】本文介绍了Node.js环境安装和项目搭建步骤。检查Node.js和npm版本安装核心依赖,如Express(Web应用框架)、MySQL库、CORS(解决跨域问题)、body-parser(解析POST数据)、express-jwt和jsonwebtoken(JWT验证)、multer(文件上传处理)、ws(WebSocket支持),以及可选的dotenv(管理环境变量)和ejs(模板引擎)。完整源码可在Gitee开源项目[nexusapi](https://gitee.com/lintaibai/nexusapi)中找到。
18 0
|
14天前
|
JavaScript Linux Python
Linux 安装 Node.js | NPM
Linux 安装 Node.js | NPM
8 0
|
20天前
node安装常用工具
node安装常用工具
9 0
|
26天前
|
数据采集 JavaScript 前端开发
❤Nodejs 第一章(认识安装)
【4月更文挑战第1天】Nodejs 是一个跨平台的 JavaScript 运行时环境,基于Chrome的V8引擎。它以异步I/O和事件驱动为特点,用于构建高效、可扩展的网络应用。Node.js 使用npm作为包管理工具,拥有大量的模块资源。它适合IO密集型应用,但不适宜CPU密集型任务。其应用场景广泛,包括前端框架、后端服务、爬虫、桌面应用、移动应用、构建工具和CICD流程等。
70 1
❤Nodejs 第一章(认识安装)
|
27天前
|
Linux Windows
教你在Linux上安装Node并用Electron打包deb和rpm包
教你在Linux上安装Node并用Electron打包deb和rpm包
32 9

热门文章

最新文章

相关产品

  • 函数计算