# 上传文件
如果你开发微信小程序或公众号H5,请移步适合的文档
上传文件分为两个步骤,获取 文件上传链接
和 上传文件
。
建议通过开放接口服务 方式上传文件。在微信云托管控制台-「微信令牌权限配置」中添加/tcb/uploadfile
.
# 获取文件上传链接
本接口应在服务器端调用,详细说明参见服务端API。
# 请求地址
POST https://api.weixin.qq.com/tcb/uploadfile?access_token=ACCESS_TOKEN
Secret置换token需要在Get参数 access_token
传token令牌使用
如果使用微信云调用令牌获取的token,Get参数名 access_token
应替换为 cloudbase_access_token
如果使用开放接口服务则不需要传Get参数 access_token
# 请求参数
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
access_token/cloudbase_access_token | string | 是 | 接口调用凭证 | |
env | string | 是 | 云环境ID | |
path | string | 是 | 上传路径 |
# 返回值
返回的 JSON 数据包
属性 | 类型 | 说明 |
---|---|---|
errcode | number | 错误码 |
errmsg | string | 错误信息 |
url | string | 上传url |
token | string | token |
authorization | string | authorization |
file_id | string | 文件ID |
cos_file_id | string | cos文件ID |
# errcode 的合法值
值 | 说明 | 最低版本 |
---|---|---|
0 | 请求成功 | |
-1 | 系统错误 | |
-1000 | 系统错误 | |
40014 | AccessToken 不合法 | |
40097 | 请求参数错误 | |
40101 | 缺少必填参数 | |
41001 | 缺少AccessToken | |
43002 | HTTP METHOD 错误 | |
44002 | POST BODY 为空 | |
47001 | POST BODY 格式错误 | |
85088 | 该APP未开通云开发 | |
其他错误码 | 错误码 |
# 请求数据示例
{
"env": "werun—id",
"path": "web/test.zip"
}
# 返回数据示例
{
"errcode": 0,
"errmsg": "ok",
"url": "https://cos.ap-shanghai.myqcloud.com/8888-werun-id-1300000000/web/test.zip",
"token": "cbl3vhld2EFYnNHa0ndCvDrmd24d6GPa9",
"authorization": "q-sign-algorithm=sha1&q-ak=AKIDFnbuKfk_qeIIhWcEFWN",
"file_id": "cloud://werun-id.8888-werun-id-1300000000/web/test.zip",
"cos_file_id": "HIqJeJmHDQoHMIlxshGWJR2mdCaaJZ96bxm=="
}
此时可以保存file_id
,用于之后对文件进行下载和删除操作
# 案例讲解
此处用PHP实现一下,需要开启开放接口服务
参照快速入门的方法,部署一个服务,代码如下:
php文件,注意替换微信云托管环境ID
<?php
if(empty($_GET["path"])) $PATH = "web/test"; // 如果没有值,则默认
else $PATH = $_GET["path"];
if(empty(getenv("CBR_ENV_ID"))) $ENVID = '微信云托管环境ID'; // 可以忽略,在本地调试时可以添加
else $ENVID = getenv("CBR_ENV_ID");
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'http://api.weixin.qq.com/tcb/uploadfile',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{"env":"'.$ENVID.'","path":"'.$PATH.'"}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json'
),
));
$response = curl_exec($curl);
curl_close($curl);
$res = json_decode($response);
$res -> key = $PATH;
echo json_encode($res);
?>
dockerFile文件如下:
FROM php:7.3-apache
COPY index.php /var/www/html/
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
CMD ["apachectl", "-DFOREGROUND"]
将两个文件组成文件夹,以文件夹形式上传版本,并部署发布
接下来访问公网域名,就可以获得信息了,访问地址参考如下,get参数 path
可以传云端路径,不要以 /
开头
# 访问自己的公网域名,此处只是示例
https://werun-id.ap-shanghai.run.tcloudbase.com/?path=web/test.zip
获取的信息结构如下:
{
"errcode": 0,
"errmsg": "ok",
"url": "https://cos.ap-shanghai.myqcloud.com/8888-werun-id-1300000000/web/test.zip",
"token": "cbl3vhld2EFYnNHa0ndCvDrmd24d6GPa9",
"authorization": "q-sign-algorithm=sha1&q-ak=AKIDFnbuKfk_qeIIhWcEFWN",
"file_id": "cloud://werun-id.8888-werun-id-1300000000/web/test.zip",
"cos_file_id": "HIqJeJmHDQoHMIlxshGWJR2mdCaaJZ96bxm==",
"key": "web/test.zip"
}
# 上传文件
用户获取到返回数据后,需拼装一个 HTTP POST 请求,其中 url 为返回包的 url 字段,Body 部分格式为 multipart/form-data,具体内容如下:
key | value | 说明 |
---|---|---|
key | this/is/a/example/file.path | 请求包中的 path 字段 |
Signature | q-sign-algorithm=sha1&q-ak=AKID9... | 返回数据的 authorization 字段 |
x-cos-security-token | Cukha70zkXIBqkh1Oh... | 返回数据的 token 字段 |
x-cos-meta-fileid | HDze32/qZENCwWi5... | 返回数据的 cos_file_id 字段。必填,否则看似上传成功的文件下载时会报错,只能删除重传。 |
file | 文件内容 | 文件的二进制内容 |
# 请求示例
curl --location --request POST 'https://cos.ap-shanghai.myqcloud.com/8888-werun-id-1300000000/web/test.zip' \
--form 'key="web/test.zip"' \
--form 'Signature="q-sign-algorithm=sha1&q-ak=AKIDFnbuKfk_qeIIhWcEFWN"' \
--form 'x-cos-security-token="cbl3vhld2EFYnNHa0ndCvDrmd24d6GPa9"' \
--form 'x-cos-meta-fileid="HIqJeJmHDQoHMIlxshGWJR2mdCaaJZ96bxm=="' \
--form 'file=@"/Users/test.zip"'
# 返回示例
无返回
# 案例讲解
我们以浏览器为例,假设你已经完成上述案例的服务构建,则html操作代码如下:
<input id="myfile" type="file"/>
<script>
const url = 'https://werun-id.ap-shanghai.run.tcloudbase.com/' // 替换自己的服务域名
const myFile = document.getElementById('myfile')
myFile.addEventListener('change', async function() {
if(myFile.value != null) {
const file = myFile.files[0];
const result = await uploadFile(file, `web/${file.name}`)
console.log('上传成功:',result)
}
})
async function uploadFile(file, path){
const resraw = await request(`${url}?path=${path}`)
const result = JSON.parse(resraw)
const data = new FormData();
data.append("key", result.key);
data.append("Signature", result.authorization);
data.append("x-cos-security-token", result.token);
data.append("x-cos-meta-fileid", result.cos_file_id);
data.append("file", file, path);
const fileraw = await request(result.url, 'POST', data)
return result.file_id
}
function request(url,method='GET',data=null){
return new Promise(function(resolve,reject){
const xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function() {
if(this.readyState === 4) {
resolve(this.responseText)
}
});
xhr.open(method, url);
xhr.send(data);
})
}
</script>
在浏览器中运行时,点击按钮上传文件,将会自动执行上传过程,最后在控制台中打印出 cloudID
如果你在本地调试,调用服务获取链接出现跨域,请在php文件的开头加上如下代码,然后重新运行
<?php
header('Access-Control-Allow-Origin: http://127.0.0.1:80'); // http://127.0.0.1:80 替换自己html页面所在域名
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Accept, Access-Control-Request-Method, Referer, Content-Type, Content-Length, Accept-Encoding');
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Credentials: true");
if(empty($_GET["path"])) $PATH = "web/test"; // 如果没有值,则默认
// ... 以下代码同上一案例
如果在上传文件过程中,遇到 cos.ap-shanghai
开头的跨域问题,则需要在对象存储-配置中添加自己html页面所在域名为安全域名。