上传文件 - Upload file
说明
本接口用于获取文件上传凭证,上传流程分为两步:
- 获取上传凭证:调用本接口,获取
uploadUrl(上传地址)和storageUri(文件存储路径) - 执行文件上传:使用
uploadUrl和formFields中的表单字段,通过httpMethod指定的方式上传文件
注意事项:
uploadUrl有效期为 10 分钟,过期后需重新获取storageUri是文件的唯一标识,上传成功后可用于其他接口(如争议质疑接口的证据 URL)- 执行表单上传时,
formFields中的所有字段都必须带上,且file字段必须放在表单的最后,否则上传会失败
请求地址 获取上传文件接口地址
HTTP
https://{{gateway_domain}}/pg/v2/file/generateUploadUrl请求参数
HTTP Method
POST
HTTP Header
| 字段 | 数据类型 | 长度限制 | 是否必填项 | 说明 |
|---|---|---|---|---|
| Content-Type | String | N/A | 是 | 字段值只支持 application/json |
| Accept | String | N/A | 是 | 字段值只支持 application/json |
| Authorization | String | 是 | Authorization: {type} {credentials},详情参考签名规范部分 |
HTTP Body
| 字段 | 数据类型 | 长度限制 | 是否必填项 | 说明 |
|---|---|---|---|---|
| filename | String | 32 | 是 | 文件名,必须包含扩展名 |
| contentType | String | 32 | 否 | 文件MIME类型,常见列表 |
| scene | String | 50 | 是 | 业务场景 |
场景说明
| 场景值 | 说明 | 支持的文件类型 | 文件大小限制 |
|---|---|---|---|
| DISPUTE_EVIDENCE | 争议质疑证据材料 | jpg, jpeg, png, pdf, xls, xlsx | 2MB |
- scene 参数大写
响应结果
HTTP Header
| 字段 | 数据类型 | 是否必填项 | 说明 |
|---|---|---|---|
| Content-Type | String | 是 | 字段值只支持 application/json |
| Authorization | String | 是 | Authorization: {type} {credentials},详情参考签名规范部分 |
HTTP Body
| 字段 | 数据类型 | 是否必填项 | 说明 |
|---|---|---|---|
| code | String | 是 | 参考响应码表 |
| errorMessage | String | 否 | 错误信息 |
| data | JSON Object | 否 |
data 字段说明
| 字段 | 数据类型 | 是否必填项 | 说明 |
|---|---|---|---|
| uploadUrl | String | 是 | 上传文件地址 URL |
| storageUri | String | 是 | 上传文件存储路径 |
| uploadNo | String | 是 | 上传编号 |
| formFields | JSON Object | 是 | 上传表单字段 |
| httpMethod | String | 是 | 上传 URL 请求方式 |
TIP
注意:formFields 中的字段个数和内容可能会根据业务需要动态变化;生产环境建议以每次响应返回的实际内容为准。示例代码中可能会为便于说明而显式列出字段。
示例
请求
HTTP
curl https://{{gateway_domain}}/pg/v2/file/generateUploadUrl \
-X POST \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H 'Authorization: V2_SHA256 appId=1111b620f93b48c5904210ff47bb1111,sign=9e494e8a91bcdd08f18ad5b2cfdbfd5654f5c00c89f8216eebd7c1637b6ce01b,timestamp=1714128828114,nonce=C7CA27DC6D55DA935DFC8450C721CC99' \
-d '{
"filename": "test.jpg",
"contentType": "image/jpeg",
"scene": "DISPUTE_EVIDENCE"
}'响应
HTTP
HTTP/1.1 200 OK
Content-Type: application/json
Server: nginx/1.18.0
Date: Mon, 06 Mar 2024 12:00:00 GMT
Authorization: V2_SHA256 appId=1111b620f93b48c5904210ff47bb1111,sign=ac6ae72f8c46f5c2092c3dab9bb0e08b6cdb6d5e7ff8ad190499a8955d57f297,timestamp=1714128245401,nonce=28FA11BF8FD1309767551B4FD8A57BD5
{
"code": "OK",
"errorMessage": null,
"data": {
"uploadUrl": "https://example.com/uploadUrl",
"storageUri": "s3://private/sssss/5fd6eeb2e00044e99f4a61eb0def66bf.jpg",
"uploadNo": "260114201050-b9219808",
"formFields": {
"bucket": "private-assets",
"key": "private/sssss/5fd6eeb2e00044e99f4a61eb0def66bf.jpg",
"x-amz-algorithm": "AWS4-HMAC-SHA256",
"x-amz-credential": "AKIA6GBMHJHZDEV2WLO7/20260114/ap-south-1/s3/aws4_request",
"x-amz-date": "20260114T144050Z",
"Content-Type": "image/jpeg",
"tagging": "<Tagging><TagSet><Tag><Key>upload-no</Key><Value>260114201050-b9219808</Value></Tag></TagSet></Tagging>",
"policy": "eyJleHBpcmF0aW9uIjoiMjAyNi0wMS0xNFQxNDo1MDo1MC4zMjYzNjQ2MTRaIiwiY29uZGl0aW9ucyI6W3siYnVja2V0IjoicHJpdmF0ZS1hc3NldHMucm9tYXBheS5pbiJ9LHsia2V5IjoibS84MC9vcGVuL2Rpc3B1dGUtZXZpZGVuY2UvOGRlNjBmOGM4YmEyNGY4Yzk3NTM0ODBjMTAwYjZmN2MucGRmIn0seyJ4LWFtei1hbGdvcml0aG0iOiJBV1M0LUhNQUMtU0hBMjU2In0seyJ4LWFtei1jcmVkZW50aWFsIjoiQUtJQTZHQk1ISkhaREVWMldMTzcvMjAyNjAxMTQvYXAtc291dGgtMS9zMy9hd3M0X3JlcXVlc3QifSx7IngtYW16LWRhdGUiOiIyMDI2MDExNFQxNDQwNTBaIn0seyJDb250ZW50LVR5cGUiOiJhcHBsaWNhdGlvbi9wZGYifSx7InRhZ2dpbmciOiI8VGFnZ2luZz48VGFnU2V0PjxUYWc+PEtleT51cGxvYWQtbm88L0tleT48VmFsdWU+MjYwMTE0MjAxMDUwLWI5MjE5ODA4PC9WYWx1ZT48L1RhZz48L1RhZ1NldD48L1RhZ2dpbmc+In0sWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsMCwyMDk3MTUyXV19",
"x-amz-signature": "479f776b70fd8b427309283fb089679492f9d19fb86fdbfeb833f4a19393d46e"
},
"httpMethod": "POST"
}
}执行上传
获取到上传凭证后,需要根据响应中的 uploadUrl、formFields 和 httpMethod,使用 multipart/form-data 格式上传文件。
重要说明
下方的 curl 命令仅作为演示示例,用于说明上传请求的格式和参数。在实际开发中,您应该使用自己项目的编程语言(如 Java、Python、Node.js 等)来实现上传逻辑。
curl 示例(仅供参考)
bash
# 这是一个 curl 示例,演示如何构造 multipart/form-data 上传请求
# 在实际项目中,请使用您的编程语言实现相同的逻辑
curl "https://example.com/uploadUrl" \
-X POST \
-F "bucket=private-assets" \
-F "key=private/sssss/5fd6eeb2e00044e99f4a61eb0def66bf.jpg" \
-F "x-amz-algorithm=AWS4-HMAC-SHA256" \
-F "x-amz-credential=AKIA6GBMHJHZDEV2WLO7/20260114/ap-south-1/s3/aws4_request" \
-F "x-amz-date=20260114T144050Z" \
-F "Content-Type=image/jpeg" \
-F "tagging=<Tagging><TagSet><Tag><Key>upload-no</Key><Value>260114201050-b9219808</Value></Tag></TagSet></Tagging>" \
-F "policy=eyJleHBpcmF0aW9uIjoiMjAyNi0wMS0xNFQxNDo1MDo1MC4zMjYzNjQ2MTRaIiwiY29uZGl0aW9ucyI6W3siYnVja2V0IjoicHJpdmF0ZS1hc3NldHMucm9tYXBheS5pbiJ9LHsia2V5IjoibS84MC9vcGVuL2Rpc3B1dGUtZXZpZGVuY2UvOGRlNjBmOGM4YmEyNGY4Yzk3NTM0ODBjMTAwYjZmN2MucGRmIn0seyJ4LWFtei1hbGdvcml0aG0iOiJBV1M0LUhNQUMtU0hBMjU2In0seyJ4LWFtei1jcmVkZW50aWFsIjoiQUtJQTZHQk1ISkhaREVWMldMTzcvMjAyNjAxMTQvYXAtc291dGgtMS9zMy9hd3M0X3JlcXVlc3QifSx7IngtYW16LWRhdGUiOiIyMDI2MDExNFQxNDQwNTBaIn0seyJDb250ZW50LVR5cGUiOiJhcHBsaWNhdGlvbi9wZGYifSx7InRhZ2dpbmciOiI8VGFnZ2luZz48VGFnU2V0PjxUYWc+PEtleT51cGxvYWQtbm88L0tleT48VmFsdWU+MjYwMTE0MjAxMDUwLWI5MjE5ODA4PC9WYWx1ZT48L1RhZz48L1RhZ1NldD48L1RhZ2dpbmc+In0sWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsMCwyMDk3MTUyXV19" \
-F "x-amz-signature=479f776b70fd8b427309283fb089679492f9d19fb86fdbfeb833f4a19393d46e" \
-F "file=@/path/to/your/test.jpg"
# ↑ 这里的 @ 符号是 curl 特有的语法,表示后面是本地文件路径
# /path/to/your/test.jpg 应替换为您电脑上的实际文件路径
# 例如 Windows: C:\Users\neo\Desktop\evidence.jpg
# 例如 macOS/Linux: /home/neo/documents/evidence.jpg各编程语言实现参考
以下是主流编程语言的实现思路,您需要根据自己项目的实际情况进行调整:
java
// 使用 Apache HttpClient
// 1. 创建 MultipartEntityBuilder
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
// 2. 遍历 formFields,将所有字段添加到表单中
for (Map.Entry<String, String> entry : formFields.entrySet()) {
builder.addTextBody(entry.getKey(), entry.getValue());
}
// 3. 最后添加文件字段(必须放在最后)
File file = new File("/Users/neo/Desktop/evidence.jpg"); // ← 您的本地文件路径
builder.addBinaryBody("file", file, ContentType.parse(contentType), file.getName());
// 4. 发送 POST 请求到 uploadUrl
HttpPost request = new HttpPost(uploadUrl);
request.setEntity(builder.build());
HttpResponse response = httpClient.execute(request);php
<?php
// 使用 cURL 扩展
// 1. 准备本地文件(替换为您的实际文件路径)
$filePath = '/Users/neo/Desktop/evidence.jpg';
// 2. 构造表单数据(formFields 中的所有字段 + file 字段放最后)
// 示例中可显式列出字段;实际以接口返回的 formFields 为准
$postFields = [
'bucket' => $formFields['bucket'],
'key' => $formFields['key'],
// ... 其他 formFields 中的所有字段(如 x-amz-*、policy、tagging 等)
'file' => new CURLFile($filePath, $contentType, basename($filePath)),
];
// 3. 初始化 cURL 并发送请求
$ch = curl_init($uploadUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);javascript
const FormData = require('form-data');
const fs = require('fs');
const path = require('path');
const axios = require('axios');
(async () => {
// 1. 创建 FormData 对象
const formData = new FormData();
// 2. 添加 formFields 中的所有字段
Object.entries(formFields).forEach(([key, value]) => {
formData.append(key, value);
});
// 3. 最后添加文件字段(替换为您的实际文件路径)
const filePath = '/Users/neo/Desktop/evidence.jpg';
formData.append('file', fs.createReadStream(filePath), {
filename: path.basename(filePath),
contentType,
});
// 4. 发送 POST 请求
const response = await axios.post(uploadUrl, formData, {
headers: formData.getHeaders(),
// 大文件时 axios 默认限制可能导致失败
maxBodyLength: Infinity,
maxContentLength: Infinity,
});
})();go
package main
import (
"bytes"
"io"
"mime/multipart"
"net/http"
"os"
"path/filepath"
)
// 1. 创建 multipart writer
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
// 2. 添加 formFields 中的所有字段
for key, value := range formFields {
_ = writer.WriteField(key, value)
}
// 3. 最后添加文件字段(替换为您的实际文件路径)
filePath := "/Users/neo/Desktop/evidence.jpg"
file, _ := os.Open(filePath)
defer file.Close()
part, _ := writer.CreateFormFile("file", filepath.Base(filePath))
io.Copy(part, file)
writer.Close()
// 4. 发送 POST 请求
req, _ := http.NewRequest("POST", uploadUrl, body)
req.Header.Set("Content-Type", writer.FormDataContentType())
client := &http.Client{}
resp, _ := client.Do(req)csharp
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
// 1. 创建 MultipartFormDataContent
using var formData = new MultipartFormDataContent();
// 2. 添加 formFields 中的所有字段
foreach (var field in formFields)
{
formData.Add(new StringContent(field.Value), field.Key);
}
// 3. 最后添加文件字段(替换为您的实际文件路径)
var filePath = "/Users/neo/Desktop/evidence.jpg";
using var fileStream = File.OpenRead(filePath);
var fileContent = new StreamContent(fileStream);
fileContent.Headers.ContentType = new MediaTypeHeaderValue(contentType);
formData.Add(fileContent, "file", Path.GetFileName(filePath));
// 4. 发送 POST 请求
using var client = new HttpClient();
var response = await client.PostAsync(uploadUrl, formData);关键要点
file字段必须放在表单的最后位置,否则上传会失败formFields中的所有字段都必须原样传递,不要修改或遗漏任何字段- 请求的
Content-Type必须是multipart/form-data(大多数 HTTP 库会自动设置) - 上传成功后,响应 HTTP 状态码为
204 No Content,无响应体