当开发者需要搭建一个 Web 应用或移动端程序时,可以使用云函数作为后端服务,由 API 网关接收客户端请求,并触发云函数处理。这样的 Serverless 架构具备简单便捷、可弹性扩展、高可用等优势,正成为越来越多人的共同选择。
但开发者在搭建应用时,难免会遇到上传文件的场景,如 App 上传用户头像、个人博客文章图片、网站评论图片,这些都需要上传文件到后端。如果您的业务托管在主机上,上传文件往往不受限制,可使用 multipart/form-data 方式直接上传文件;但在 Serverless架构下,由于 API 网关和云函数之间只支持传输 JSON 数据,使用传统方式上传文件较为困难,一般的解决方案是由客户端通过 Base64 等算法,先将文件从二进制转换为字符后再进行上传。
近期腾讯云 Serverless 团队优化了上传文件体验,上线了 API 网关 Base64 编码功能,上传文件时原本由客户端做的 Base64 编码过程变为由 API 网关进行,这使得开发者无需改动客户端代码即可将二进制文件上传至云函数 SCF。同时,前端开发中一般可基于 Base64 格式完成图片的存储和展现,使得该功能对前端开发者来说非常友好。
本文对 Serverless 和传统方式 multipart 上传多文件的过程进行了对比,并介绍了Base64 编码功能的配置方式。
如果您的后端服务托管在云主机上,一般上传文件的请求过程如下:
以下是一段客户端上传两张图片 pic-1.jpg 和 pic-2.jpg 到后端服务的 Python 3 参考代码:
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
from requests_toolbelt.multipart import decoder
m = MultipartEncoder(
fields=[
('files[]',('file.jpg', open('pic-2.jpg', 'rb'), 'image/jpeg')),
('files[]',('file2.jpg', open('pic-1.jpg', 'rb'), 'image/jpeg')),
]
)
res = requests.post(url='https://yourwebsite.com/upload',
data=m,
headers={'Content-Type': m.content_type})
json = res.json()
print(json)
如图是采用 API 网关结合云函数,开启 Base64 功能后上传文件的请求过程:
通过以上两种方式的对比,我们不难看出,Base64编码功能的最大优势在于使 Serverless 获得了和传统方式完全一致的上传文件体验,可直接使用传统方式的客户端代码进行上传。
另外,在云函数中获取了经过 Base64 编码的文本后,您只需对 event.body 进行解码,就可以得到二进制文件了。以下是一段在云函数中解码多文件的 Python 3 参考代码:
# -*- coding: utf-8 -*-
import sys
import logging
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
from requests_toolbelt.multipart import decoder
import base64
import json
print('Loading function')
logger = logging.getLogger()
def main_handler(event, context):
logger.info("start main handler")
content_type_header = event['headers']['content-type']
body = event['body']
is_me = base64.b64decode(body)
for part in decoder.MultipartDecoder(is_me, content_type_header).parts:
print(part.content)注意:需要使用层或上传 zip 包的形式安装相关依赖。
为满足不同场景的要求,Base64 编码功能还提供了“全部触发”和“Header 触发”两种触发方式供您选择:
以下将分别叙述两种触发方式的配置过程:


传送门:
- GitHub: github.com/serverless
- 官网:serverless.com
欢迎访问:Serverless 中文网,您可以在 最佳实践 里体验更多关于 Serverless 应用的开发!