前言
当开发者需要搭建一个 Web 应用或移动端程序时,可以使用云函数作为后端服务,由 API 网关接收客户端请求,并触发云函数处理。这样的 Serverless 架构具备简单便捷、可弹性扩展、高可用等优势,正成为越来越多人的共同选择。
但开发者在搭建应用时,难免会遇到上传文件的场景,如 App 上传用户头像、个人博客文章图片、网站评论图片,这些都需要上传文件到后端。如果您的业务托管在主机上,上传文件往往不受限制,可使用 multipart/form-data 方式直接上传文件;但在 Serverless架构下,由于 API 网关和云函数之间只支持传输 JSON 数据,使用传统方式上传文件较为困难,一般的解决方案是由客户端通过 Base64 等算法,先将文件从二进制转换为字符后再进行上传。
近期腾讯云 Serverless 团队优化了上传文件体验,上线了 API 网关 Base64 编码功能,上传文件时原本由客户端做的 Base64 编码过程变为由 API 网关进行,这使得开发者无需改动客户端代码即可将二进制文件上传至云函数 SCF。同时,前端开发中一般可基于 Base64 格式完成图片的存储和展现,使得该功能对前端开发者来说非常友好。
本文对 Serverless 和传统方式 multipart 上传多文件的过程进行了对比,并介绍了Base64 编码功能的配置方式。
请求过程对比
传统方式上传文件过程
如果您的后端服务托管在云主机上,一般上传文件的请求过程如下:
- 第一步:客户端可直接使用 multipart/form-data 方式上传文件;
- 第二步:在后端服务中获取二进制文件。
以下是一段客户端上传两张图片 pic-1.jpg 和 pic-2.jpg 到后端服务的 Python 3 参考代码:
代码语言:javascript复制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)
Serverless 上传文件过程
如图是采用 API 网关结合云函数,开启 Base64 功能后上传文件的请求过程:
- 客户端可直接使用 multipart/form-data 方式上传文件;
- 在云函数中获取经过 Base64 编码的文本。
对比结论
通过以上两种方式的对比,我们不难看出,Base64编码功能的最大优势在于使 Serverless 获得了和传统方式完全一致的上传文件体验,可直接使用传统方式的客户端代码进行上传。
另外,在云函数中获取了经过 Base64 编码的文本后,您只需对 event.body 进行解码,就可以得到二进制文件了。以下是一段在云函数中解码多文件的 Python 3 参考代码:
代码语言:javascript复制# -*- 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 触发”两种触发方式供您选择:
- 全部触发:API 开启全部触发后,每次请求的请求内容都会被 Base64 编码后再传递给云函数。
- Header 触发:API 开启 Header 触发后,必须配置触发规则。API 网关将根据触发规则对请求头进行校验,只有拥有特定 Content-Type 或 Accept 请求头的请求会被 Base64 编码后再传递给云函数,不满足条件的请求将不进行 Base64 编码,直接传递给云函数。
以下将分别叙述两种触发方式的配置过程:
配置全部触发
- 登录 API 网关控制台 ,在左侧导航栏单击【服务】。
- 在服务列表中,单击目标服务的服务 ID,查看 API 列表。
- 单击【新建】,填写 API 前端配置,单击【下一步】。
- API 后端类型选择【云函数SCF】,勾选“Base64编码”,完成后续配置流程。此时创建的 API 已经开启了 Base64 编码,并默认为“全部触发”。
配置 Header 触发
- 登录 API 网关控制台 ,在左侧导航栏单击【服务】。
- 在服务列表中,单击目标服务的服务 ID,查看 API 列表。
- 在 API 列表中,单击目标 API 的 API ID(目标 API 必须是后端对接 SCF 的 API),即可查看 API 详情页。在 API 详情页中,单击【基础配置】标签页,找到【Base64编码】配置项。
- 单击"Base64"后的【编辑】,选择触发方式为【Header触发】。单击【添加触发规则】,选择参数并填写参数值。
- 确认配置信息无误后,最后单击【保存】即可。
One More Thing
立即体验腾讯云 Serverless Demo,获取 Serverless 新用户礼包,请在 PC 端访问: serverless.cloud.tencent.com/start?c=wx
欢迎进入千人 QQ 群 (537539545) 交流!
- GitHub: github.com/serverless
- 官网: cloud.tencent.com/product/serverless-catalog
点击「阅读原文」进入 Serverless 中文网,体验更多 Serverless 应用的最佳实践!