最近的一个小程序项目中直接对接氚云图片显示,因氚云不能直接访问图片,所以使用了中间件将图片下载后转为base64再加载到小程序中。
中件间服务代码在最下面
H3yun Image to Base64 API 文档
概述
本接口用于通过氚云平台的 DownloadBizObjectFile
接口下载指定附件(图片),并将其转换为 Base64 编码字符串返回。接口支持单一附件 ID 的处理,适用于需要将图片嵌入网页、邮件或其他场景。
接口地址:http://<your-server>:5000/image_to_base64
请求方式:POST
协议:HTTP/HTTPS
请求参数
请求头(Header)
参数名 | 类型 | 是否必填 | 描述 | 示例值 |
---|---|---|---|---|
EngineCode | String | 是 | 氚云企业引擎编码 | |
EngineSecret | String | 是 | 氚云企业引擎密钥 | |
Content-Type | String | 是 | 请求内容类型,推荐 application/x-www-form-urlencoded | application/x-www-form-urlencoded |
请求体(Body)
请求体使用 application/x-www-form-urlencoded
格式,包含以下参数:
参数名 | 类型 | 是否必填 | 描述 | 示例值 |
---|---|---|---|---|
attachmentId | String | 是 | 氚云附件 ID | 2b5dba74-3e77-4cdc-863d-76e13249adf3 |
EngineCode | String | 是 | 氚云企业引擎编码(必须与请求头中的 EngineCode 一致) |
响应格式
响应为 JSON 格式,包含以下字段:
字段名 | 类型 | 描述 | 示例值 |
---|---|---|---|
code | Integer | 响应状态码,200 表示成功 | 200 |
message | String | 响应消息 | 成功 |
data | Object | 成功时的返回数据 | {"image_base64": "iVBORw0KGgoAAAANSUhEUg..."} |
成功响应示例
{
"code": 200,
"message": "成功",
"data": {
"image_base64": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6ZAAAAABJRU5ErkJggg=="
}
}
失败响应示例
- 缺少参数:
{
"code": 400,
"message": "缺少必需参数"
}
- EngineCode 不一致:
{
"code": 400,
"message": "EngineCode 不一致"
}
- 氚云接口失败:
{
"code": 403,
"message": "从氚云下载图片失败"
}
- 服务器错误:
{
"code": 500,
"message": "服务器错误: <具体错误信息>"
}
错误码
错误码 | 描述 |
---|---|
200 | 请求成功 |
400 | 请求参数错误(如缺少参数、EngineCode 不一致) |
403 | 氚云接口认证失败 |
404 | 氚云附件不存在 |
500 | 服务器内部错误 |
使用示例
Python 示例
import requests
url = 'http://127.0.0.1:5000/image_to_base64'
headers = {
'EngineCode': 'EngineCode',
'EngineSecret': 'EngineSecret',
'Content-Type': 'application/x-www-form-urlencoded'
}
data = {
'attachmentId': '2b5dba74-3e77-4cdc-863d-76e13249adf3',
'EngineCode': 'EngineCode'
}
try:
response = requests.post(url, headers=headers, data=data)
print(f"状态码: {response.status_code}")
print("响应 JSON:", response.json())
except requests.exceptions.RequestException as e:
print(f"请求出错: {str(e)}")
cURL 示例
curl -X POST http://127.0.0.1:5000/image_to_base64 \
-H "EngineCode: jplm1jv9yalwbd017pmef57f0" \
-H "EngineSecret: 0rfdZ9BA8DXOBMikyt2V1cVU9479XlxigUjRHLK6kwTisQ26OmH5wQ==" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "attachmentId=2b5dba74-3e77-4cdc-863d-76e13249adf3&EngineCode=jplm1jv9yalwbd017pmef57f0"
注意事项
-
参数一致性:
- 请求头和请求体中的
EngineCode
必须完全一致,否则返回 400 错误。 - 确保
EngineCode
和EngineSecret
是氚云平台提供的有效值。
- 请求头和请求体中的
-
附件 ID 有效性:
attachmentId
必须是氚云平台上存在的附件 ID,否则氚云接口可能返回错误(如 404 或 403)。
-
网络要求:
- 服务器需能访问
https://www.h3yun.com/Api/DownloadBizObjectFile
。 - 确保无防火墙或代理阻止请求。
- 服务器需能访问
-
日志调试:
- 接口启用详细日志(DEBUG 级别),记录请求参数、氚云接口响应状态和 Base64 转换详情。
- 检查服务器日志以排查问题,日志格式为:
[时间] [级别] 消息
。
-
性能:
- 当前接口每次请求处理单一附件 ID,适合小规模使用。
python中间件服务代码如下:
from flask import Flask, request, jsonify
import requests
import base64
import logging
from datetime import datetime
# 配置日志
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s [%(levelname)s] %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger(__name__)
app = Flask(__name__)
@app.route('/image_to_base64', methods=['POST'])
def image_to_base64():
try:
# 记录请求开始
logger.info("收到新的 /image_to_base64 请求")
# 获取请求头参数
engine_code = request.headers.get('EngineCode')
engine_secret = request.headers.get('EngineSecret')
content_type = request.headers.get('Content-Type')
# 记录请求头参数
logger.debug(f"请求头参数 - EngineCode: {engine_code}")
logger.debug(f"请求头参数 - EngineSecret: {engine_secret}")
logger.debug(f"请求头参数 - Content-Type: {content_type}")
# 获取表单参数
attachment_id = request.form.get('attachmentId')
form_engine_code = request.form.get('EngineCode')
# 记录表单参数
logger.debug(f"表单参数 - attachmentId: {attachment_id}")
logger.debug(f"表单参数 - EngineCode: {form_engine_code}")
# 验证必需参数
if not all([engine_code, engine_secret, content_type, attachment_id, form_engine_code]):
logger.error("缺少必需参数")
return jsonify({
'code': 400,
'message': '缺少必需参数'
}), 400
# 验证 EngineCode 一致性
if engine_code != form_engine_code:
logger.error("EngineCode 不一致")
return jsonify({
'code': 400,
'message': 'EngineCode 不一致'
}), 400
# 构造下载请求
url = 'https://www.h3yun.com/Api/DownloadBizObjectFile'
headers = {
'EngineCode': engine_code,
'EngineSecret': engine_secret,
'Content-Type': 'application/x-www-form-urlencoded' # 适配氚云接口
}
data = {
'attachmentId': attachment_id,
'EngineCode': engine_code
}
logger.info(f"向氚云服务器发送请求: {url}")
logger.debug(f"氚云请求头: {headers}")
logger.debug(f"氚云请求数据: {data}")
# 发送请求下载图片
response = requests.post(url, headers=headers, data=data)
# 检查响应状态
logger.debug(f"氚云服务器响应状态码: {response.status_code}")
if response.status_code != 200:
logger.error(f"从氚云下载图片失败,状态码: {response.status_code}")
return jsonify({
'code': response.status_code,
'message': '从氚云下载图片失败'
}), response.status_code
# 将图片转为 Base64
img_binary = response.content
img_base64 = base64.b64encode(img_binary).decode('utf-8')
logger.info("图片成功转换为 Base64")
logger.debug(f"Base64 字符串长度: {len(img_base64)}")
return jsonify({
'code': 200,
'message': '成功',
'data': {
'image_base64': img_base64
}
})
except Exception as e:
logger.exception(f"服务器错误: {str(e)}")
return jsonify({
'code': 500,
'message': f'服务器错误: {str(e)}'
}), 500
if __name__ == '__main__':
logger.info("启动 Flask 服务器")
app.run(debug=True)
再使用php也写一个(和python的功能是相同的)
<?php
// 处理 CORS
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: EngineCode, EngineSecret, Content-Type');
// 设置响应内容类型
header('Content-Type: application/json');
// 自定义日志函数
function log_message($level, $message) {
$timestamp = date('Y-m-d H:i:s');
error_log("[$timestamp] [$level] $message");
}
// 处理请求
try {
log_message('INFO', '收到新的 /image_to_base64 请求');
// 获取请求头参数
$headers = getallheaders();
$engine_code = isset($headers['EngineCode']) ? $headers['EngineCode'] : (isset($_SERVER['HTTP_ENGINECODE']) ? $_SERVER['HTTP_ENGINECODE'] : null);
$engine_secret = isset($headers['EngineSecret']) ? $headers['EngineSecret'] : (isset($_SERVER['HTTP_ENGINESECRET']) ? $_SERVER['HTTP_ENGINESECRET'] : null);
$content_type = isset($headers['Content-Type']) ? $headers['Content-Type'] : (isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : null);
// 记录请求头参数
log_message('DEBUG', "请求头参数 - EngineCode: " . ($engine_code ?? 'null'));
log_message('DEBUG', "请求头参数 - EngineSecret: " . ($engine_secret ?? 'null'));
log_message('DEBUG', "请求头参数 - Content-Type: " . ($content_type ?? 'null'));
// 获取表单参数
$attachment_id = isset($_POST['attachmentId']) ? $_POST['attachmentId'] : null;
$form_engine_code = isset($_POST['EngineCode']) ? $_POST['EngineCode'] : null;
// 记录表单参数
log_message('DEBUG', "表单参数 - attachmentId: " . ($attachment_id ?? 'null'));
log_message('DEBUG', "表单参数 - EngineCode: " . ($form_engine_code ?? 'null'));
// 记录原始请求体
$raw_input = file_get_contents('php://input');
log_message('DEBUG', "原始请求体: " . $raw_input);
// 验证必需参数
$missing_params = [];
if (empty($engine_code)) $missing_params[] = 'EngineCode (header)';
if (empty($engine_secret)) $missing_params[] = 'EngineSecret (header)';
if (empty($content_type)) $missing_params[] = 'Content-Type (header)';
if (empty($attachment_id)) $missing_params[] = 'attachmentId (body)';
if (empty($form_engine_code)) $missing_params[] = 'EngineCode (body)';
if (!empty($missing_params)) {
$error_message = '缺少必需参数: ' . implode(', ', $missing_params);
log_message('ERROR', $error_message);
http_response_code(400);
echo json_encode([
'code' => 400,
'message' => $error_message
]);
exit;
}
// 验证 EngineCode 一致性
if ($engine_code !== $form_engine_code) {
log_message('ERROR', 'EngineCode 不一致');
http_response_code(400);
echo json_encode([
'code' => 400,
'message' => 'EngineCode 不一致'
]);
exit;
}
// 构造下载请求
$url = 'https://www.h3yun.com/Api/DownloadBizObjectFile';
$headers = [
'EngineCode: ' . $engine_code,
'EngineSecret: ' . $engine_secret,
'Content-Type: application/x-www-form-urlencoded'
];
$data = [
'attachmentId' => $attachment_id,
'EngineCode' => $engine_code
];
log_message('INFO', "向氚云服务器发送请求: $url");
log_message('DEBUG', '氚云请求头: ' . json_encode($headers));
log_message('DEBUG', '氚云请求数据: ' . json_encode($data));
// 使用 cURL 发送请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
// 禁用 SSL 验证(仅限调试)
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
$error_no = curl_errno($ch);
curl_close($ch);
// 检查响应状态
log_message('DEBUG', "氚云服务器响应状态码: $http_code");
log_message('DEBUG', "cURL 错误码: $error_no");
if ($error) {
log_message('ERROR', "氚云请求失败: $error");
http_response_code(500);
echo json_encode([
'code' => 500,
'message' => "氚云请求失败: $error"
]);
exit;
}
if ($http_code != 200) {
log_message('ERROR', "从氚云下载图片失败,状态码: $http_code");
http_response_code($http_code);
echo json_encode([
'code' => $http_code,
'message' => '从氚云下载图片失败'
]);
exit;
}
// 将图片转为 Base64
$img_base64 = base64_encode($response);
log_message('INFO', '图片成功转换为 Base64');
log_message('DEBUG', 'Base64 字符串长度: ' . strlen($img_base64));
// 返回响应
echo json_encode([
'code' => 200,
'message' => '成功',
'data' => [
'image_base64' => $img_base64
]
]);
} catch (Exception $e) {
log_message('ERROR', "服务器错误: " . $e->getMessage());
http_response_code(500);
echo json_encode([
'code' => 500,
'message' => '服务器错误: ' . $e->getMessage()
]);
}
?>