This commit is contained in:
2024-10-29 14:04:59 +08:00
commit 48bf3e6f33
2839 changed files with 762707 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
<h3 lay-toc="{level: 2, id: 'examples', hot: true}" class="layui-hide">图片上传</h3>
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 535px;', text: {preview: '图片上传'}, layout: ['preview', 'code'], tools: ['full'], done: function(obj){
obj.render();
}}">
<textarea>
{{- d.include("/upload/examples/image.md") }}
</script>
</textarea>
</pre>
<h3 id="demo-files-table" lay-toc="{level: 2}">制作多文件上传表格</h3>
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 535px;', layout: ['preview', 'code'], tools: ['full']}">
<textarea>
{{- d.include("/upload/examples/files.table.md") }}
</textarea>
</pre>
<h3 id="demo-accept" lay-toc="{level: 2}">过滤文件类型</h3>
<pre class="layui-code" lay-options="{preview: true, codeStyle: 'height: 535px;', layout: ['preview', 'code'], tools: ['full']}">
<textarea>
{{- d.include("/upload/examples/accept.md") }}
</textarea>
</pre>
<h3 id="demo-size" lay-toc="{level: 2}">限制文件大小</h3>
<pre class="layui-code" lay-options="{preview: true, layout: ['preview', 'code'], tools: ['full']}">
<textarea>
{{- d.include("/upload/examples/size.md") }}
</textarea>
</pre>
<h3 id="demo-auto" lay-toc="{level: 2}">选择后手动上传</h3>
<pre class="layui-code" lay-options="{preview: true, layout: ['preview', 'code'], tools: ['full']}">
<textarea>
{{- d.include("/upload/examples/auto.md") }}
</textarea>
</pre>
<h3 id="demo-drag" lay-toc="{level: 2}">拖拽上传</h3>
<pre class="layui-code" lay-options="{preview: true, layout: ['preview', 'code'], tools: ['full']}">
<textarea>
{{- d.include("/upload/examples/drag.md") }}
</textarea>
</pre>
<h3 id="demo-form-file" lay-toc="{level: 2}">绑定原始文件域</h3>
<pre class="layui-code" lay-options="{preview: true, layout: ['preview', 'code'], tools: ['full']}">
<textarea>
{{- d.include("/upload/examples/form.file.md") }}
</textarea>
</pre>

View File

@@ -0,0 +1,483 @@
<table class="layui-table">
<colgroup>
<col width="150">
<col>
<col width="100">
<col width="100">
</colgroup>
<thead>
<tr>
<th>属性名</th>
<th>描述</th>
<th>类型</th>
<th>默认值</th>
</tr>
</thead>
<tbody>
<tr>
<td>elem</td>
<td>
绑定元素选择器或 DOM 对象
</td>
<td>string/DOM</td>
<td>-</td>
</tr>
<tr>
<td>url</td>
<td>
上传接口
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>field</td>
<td>
文件域的字段名
</td>
<td>string</td>
<td>
`file`
</td>
</tr>
<tr>
<td>
[data](#options.data)
</td>
<td>
<div id="options.data" lay-pid="options" class="ws-anchor">
传递给上传接口的额外参数,支持静态赋值和动态赋值两种写法。
</div>
- 静态赋值 :
```
data: {
id: '123'
}
```
- 动态赋值 :
```
data: {
id: function(){
return $('#id').val();
}
}
```
</td>
<td>object</td>
<td>-</td>
</tr>
<tr>
<td>headers</td>
<td>
上传接口的请求头。如 `headers: {token: 'abc123'}`
</td>
<td>object</td>
<td>-</td>
</tr>
<tr>
<td>dataType <sup>2.8.17+</sup></td>
<td>
服务端返回的数据类型,如:`text,json,xml`
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>
[accept](#options.accept)
</td>
<td>
<div id="options.accept" lay-pid="options" class="ws-anchor">
指定允许上传时校验的文件类型。可选值有:
</div>
- `images` 图片类型
- `file` 所有文件类型
- `video` 视频类型
- `audio` 音频类型
</td>
<td>string</td>
<td>
`images`
</td>
</tr>
<tr>
<td>acceptMime</td>
<td>
规定打开系统的文件选择框时,筛选出的文件类型,多个 `MIME` 类型可用逗号隔开。示例:
```
acceptMime: 'image/*'` // 筛选所有图片类型
acceptMime: 'image/jpeg, image/png` // 只筛选 jpg,png 格式图片
```
更多可选值参考: <a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types" target="_blank">MIME 类型</a>
</td>
<td>string</td>
<td>-</td>
</tr>
<tr>
<td>
[exts](#options.exts)
</td>
<td>
<div id="options.exts" lay-pid="options" class="ws-anchor">
允许上传的文件后缀。一般结合 `accept` 属性来设定。
</div>
- 假设 `accept: 'file'` 类型时,那么设置 `exts: 'zip|rar|7z'` 即代表只允许上传压缩格式的文件。
- 默认为常见图片后缀,即 `jpg|png|gif|bmp|jpeg|svg`
</td>
<td>string</td>
<td>
见左
</td>
</tr>
<tr>
<td>auto</td>
<td>
是否选完文件后自动上传。若为 `false`,则需设置 `bindAction` 属性来指向其它按钮提交上传。参考:[#示例](#demo-auto)
</td>
<td>boolean</td>
<td>
`true`
</td>
</tr>
<tr>
<td>bindAction</td>
<td>
设置触发上传的元素选择器或 DOM 对象。
<br>一般配合 `auto: false` 来使用。详细用法参考:[#示例](#demo-auto)
</td>
<td>string/DOM</td>
<td>-</td>
</tr>
<tr>
<td>force <sup>2.6.9+</sup></td>
<td>
规定强制返回的数据格式。
- 若值为 `'json'`,则强制校验 JSON 数据格式
</td>
<td>string</td>
<td>
`null`
</td>
</tr>
<tr>
<td>size</td>
<td>
设置文件最大可允许上传的大小,单位 `KB` 。默认不限制。
<br>不支持 `ie8/9`
</td>
<td>number</td>
<td>
`0`
</td>
</tr>
<tr>
<td>multiple</td>
<td>
是否允许多文件上传。不支持 `ie8/9`
</td>
<td>boolean</td>
<td>
`false`
</td>
</tr>
<tr>
<td>unified <sup>2.8.8+</sup></td>
<td>
选择多文件时,是否统一上传,即只发送一次请求。
</td>
<td>boolean</td>
<td>
`false`
</td>
</tr>
<tr>
<td>number</td>
<td>
同时可上传的文件数量,一般当 `multiple: true` 时使用。
</td>
<td>number</td>
<td>-</td>
</tr>
<tr>
<td>drag</td>
<td>
是否接受拖拽的文件上传。
</td>
<td>boolean</td>
<td>
`true`
</td>
</tr>
<tr>
<td>
[text](#options.text) <sup>2.8.9+</sup>
</td>
<td colspan="4">
<div id="options.text" lay-pid="options" class="ws-anchor">
自定义内部各类场景下的提示文本
</div>
```
text: { // 自定义提示文本
"data-format-error": "", // 数据格式错误的提示
"check-error": "", // 文件格式校验失败的提示
"error": "", // 上传失败的提示
"limit-number": null, // 限制 number 属性的提示。若设置,需为函数写法
"limit-size": null, // 限制 size 属性的提示。若设置,需为函数写法
"cross-domain": "", // IE 下跨域的提示
}
```
</td>
</tr>
<tr>
<td colspan="4" style="text-align: center">
<div id="options.callback" lay-pid="options" class="ws-anchor">
[回调函数](#options.callback)
</div>
</td>
</tr>
<tr>
<td>
[choose](#options.choose)
</td>
<td colspan="3">
<div id="options.choose" lay-pid="options" class="ws-anchor">
选择文件后的回调函数。返回的参数如下
</div>
```
choose: function(obj){
// 将每次选择的文件追加到文件队列
var files = obj.pushFile();
// 预读本地文件,如果是多文件,则会遍历。(不支持ie8/9)
obj.preview(function(index, file, result){
console.log(index); // 得到文件索引
console.log(file); // 得到文件对象
console.log(result); // 得到文件base64编码比如图片
// obj.resetFile(index, file, '123.jpg'); // 重命名文件名
// 这里还可以做一些 append 文件列表 DOM 的操作
// obj.upload(index, file); // 对上传失败的单个文件重新上传,一般在某个事件中使用
// delete files[index]; //删除列表中对应的文件,一般在某个事件中使用
});
}
```
详细用法参考:[#示例](#demo-files-table)
</td>
</tr>
<tr>
<td>
[before](#options.before)
</td>
<td colspan="3">
<div id="options.before" lay-pid="options" class="ws-anchor">
文件提交上传前的回调函数。返回的参数同 choose
</div>
```
before: function(obj){ // obj 参数同 choose
layer.load(); // 上传 loading
// 若返回 false则表明阻止上传
/*
if(true){
return false;
}
*/
}
```
</td>
</tr>
<tr>
<td>
[progress](#options.progress)
</td>
<td colspan="3">
<div id="options.progress" lay-pid="options" class="ws-anchor">
执行上传请求后的回调函数。返回的参数如下:
</div>
```
progress: function(n, elem, res, index){
var percent = n + '%' // 获取进度百分比
element.progress('demo', percent); // 可配合 layui 进度条元素使用
// 得到当前触发的元素 DOM 对象
console.log(elem); // 可通过该元素定义的属性值匹配到对应的进度条。
console.log(res); // 得到 progress 响应信息
console.log(index); // 得到当前上传文件的索引,多文件上传时的进度条控制
element.progress('demo-'+ index, n + '%'); // 进度条
}
```
详细用法参考:[#示例](#examples)
</td>
</tr>
<tr>
<td>
[done](#options.done)
</td>
<td colspan="3">
<div id="options.done" lay-pid="options" class="ws-anchor">
执行单次文件上传请求后的回调函数。返回的参数如下:
</div>
```
done: function(res, index, upload){
// 假设 `code: 0` 代表上传成功
if(res.code == 0){
// do something // 比如将 res 返回的图片链接保存到隐藏域
}
// 获取当前触发上传的元素,一般用于 elem 绑定 class 的情况
var item = this.item;
// …
}
```
详细用法参考:[#示例](#examples)
</td>
</tr>
<tr>
<tr>
<td>
[allDone](#options.allDone)
</td>
<td colspan="3">
<div id="options.allDone" lay-pid="options" class="ws-anchor">
当开启多文件 (`multiple: true` ) 且所有文件均上传完毕后的状态回调函数。
</div>
```
allDone: function(obj){
console.log(obj.total); // 上传的文件总数
console.log(obj.successful); // 上传成功的文件数
console.log(obj.failed); // 上传失败的文件数
}
```
</td>
</tr>
<tr>
<td>error</td>
<td colspan="3">
执行上传请求出现异常的回调一般为网络异常、URL 404等。返回两个参数如下
```
error: function(index, upload){
console.log(index); // 当前文件的索引
// upload(); 重新上传的方法
}
```
</td>
</tr>
</tbody>
</table>

View File

@@ -0,0 +1,40 @@
<div class="layui-btn-container">
<button type="button" class="layui-btn demo-class-accept" lay-options="{accept: 'file'}">
<i class="layui-icon layui-icon-upload"></i>
上传文件
</button>
<button type="button" class="layui-btn demo-class-accept" lay-options="{
accept: 'file',
exts: 'zip|rar|7z'
}">
<i class="layui-icon layui-icon-upload"></i>
只允许压缩文件
</button>
<button type="button" class="layui-btn demo-class-accept" lay-options="{accept: 'video'}">
<i class="layui-icon layui-icon-upload"></i>
上传视频
</button>
<button type="button" class="layui-btn demo-class-accept" lay-options="{accept: 'audio'}">
<i class="layui-icon layui-icon-upload"></i>
上传音频
</button>
</div>
<!-- import layui -->
<script>
layui.use(function(){
var upload = layui.upload;
var layer = layui.layer;
// 渲染
upload.render({
elem: '.demo-class-accept', // 绑定多个元素
url: '', // 此处配置你自己的上传接口即可
accept: 'file', // 普通文件
done: function(res){
layer.msg('上传成功');
console.log(res);
}
});
});
</script>

View File

@@ -0,0 +1,24 @@
<div class="layui-btn-container">
<button type="button" class="layui-btn layui-btn-normal" id="ID-upload-demo-choose">选择文件</button>
<button type="button" class="layui-btn" id="ID-upload-demo-action">开始上传</button>
</div>
<!-- import layui -->
<script>
layui.use(function(){
var upload = layui.upload;
// 渲染
upload.render({
elem: '#ID-upload-demo-choose',
url: '', // 此处配置你自己的上传接口即可
auto: false,
// multiple: true,
bindAction: '#ID-upload-demo-action',
done: function(res){
layer.msg('上传成功');
console.log(res)
}
});
});
</script>

View File

@@ -0,0 +1,27 @@
<div class="layui-upload-drag" style="display: block;" id="ID-upload-demo-drag">
<i class="layui-icon layui-icon-upload"></i>
<div>点击上传,或将文件拖拽到此处</div>
<div class="layui-hide" id="ID-upload-demo-preview">
<hr> <img src="" alt="上传成功后渲染" style="max-width: 100%">
</div>
</div>
<!-- import layui -->
<script>
layui.use(function(){
var upload = layui.upload;
var $ = layui.$;
// 渲染
upload.render({
elem: '#ID-upload-demo-drag',
url: 'https://httpbin.org/post', // 此处用的是第三方的 http 请求演示,实际使用时改成您自己的上传接口即可。
done: function(res){
layer.msg('上传成功');
$('#ID-upload-demo-preview').removeClass('layui-hide')
.find('img').attr('src', res.files.file);
console.log(res)
}
});
});
</script>

View File

@@ -0,0 +1,99 @@
<div class="layui-upload">
<button type="button" class="layui-btn layui-btn-normal" id="ID-upload-demo-files">选择多文件</button>
<div class="layui-upload-list">
<table class="layui-table">
<colgroup>
<col style="min-width: 100px;">
<col width="150">
<col width="260">
<col width="150">
</colgroup>
<thead>
<th>文件名</th>
<th>大小</th>
<th>上传进度</th>
<th>操作</th>
</thead>
<tbody id="ID-upload-demo-files-list"></tbody>
</table>
</div>
<button type="button" class="layui-btn" id="ID-upload-demo-files-action">开始上传</button>
</div>
<!-- import layui -->
<script>
layui.use(function(){
var upload = layui.upload;
var element = layui.element;
var $ = layui.$;
// 制作多文件上传表格
var uploadListIns = upload.render({
elem: '#ID-upload-demo-files',
elemList: $('#ID-upload-demo-files-list'), // 列表元素对象
url: 'https://httpbin.org/post', // 此处用的是第三方的 http 请求演示,实际使用时改成您自己的上传接口即可。
accept: 'file',
multiple: true,
number: 3,
auto: false,
bindAction: '#ID-upload-demo-files-action',
choose: function(obj){
var that = this;
var files = this.files = obj.pushFile(); // 将每次选择的文件追加到文件队列
// 读取本地文件
obj.preview(function(index, file, result){
var tr = $(['<tr id="upload-'+ index +'">',
'<td>'+ file.name +'</td>',
'<td>'+ (file.size/1024).toFixed(1) +'kb</td>',
'<td><div class="layui-progress" lay-filter="progress-demo-'+ index +'"><div class="layui-progress-bar" lay-percent=""></div></div></td>',
'<td>',
'<button class="layui-btn layui-btn-xs demo-reload layui-hide">重传</button>',
'<button class="layui-btn layui-btn-xs layui-btn-danger demo-delete">删除</button>',
'</td>',
'</tr>'].join(''));
// 单个重传
tr.find('.demo-reload').on('click', function(){
obj.upload(index, file);
});
// 删除
tr.find('.demo-delete').on('click', function(){
delete files[index]; // 删除对应的文件
tr.remove(); // 删除表格行
// 清空 input file 值,以免删除后出现同名文件不可选
uploadListIns.config.elem.next()[0].value = '';
});
that.elemList.append(tr);
element.render('progress'); // 渲染新加的进度条组件
});
},
done: function(res, index, upload){ // 成功的回调
var that = this;
// if(res.code == 0){ // 上传成功
var tr = that.elemList.find('tr#upload-'+ index)
var tds = tr.children();
tds.eq(3).html(''); // 清空操作
delete this.files[index]; // 删除文件队列已经上传成功的文件
return;
//}
this.error(index, upload);
},
allDone: function(obj){ // 多文件上传完毕后的状态回调
console.log(obj)
},
error: function(index, upload){ // 错误回调
var that = this;
var tr = that.elemList.find('tr#upload-'+ index);
var tds = tr.children();
// 显示重传
tds.eq(3).find('.demo-reload').removeClass('layui-hide');
},
progress: function(n, elem, e, index){ // 注意index 参数为 layui 2.6.6 新增
element.progress('progress-demo-'+ index, n + '%'); // 执行进度条。n 即为返回的进度百分比
}
});
});
</script>

View File

@@ -0,0 +1,19 @@
<input type="file" name="file" id="ID-upload-demo-form-files">
<!-- import layui -->
<script>
layui.use(function(){
var upload = layui.upload;
var layer = layui.layer
// 渲染
upload.render({
elem: '#ID-upload-demo-form-files',
url: '', // 此处配置你自己的上传接口即可
done: function(res){
layer.msg('上传成功');
console.log(res)
}
});
});
</script>

View File

@@ -0,0 +1,87 @@
<button type="button" class="layui-btn" id="ID-upload-demo-btn">
<i class="layui-icon layui-icon-upload"></i> 单图片上传
</button>
<div style="width: 132px;">
<div class="layui-upload-list">
<img class="layui-upload-img" id="ID-upload-demo-img" style="width: 100%; height: 92px;">
<div id="ID-upload-demo-text"></div>
</div>
<div class="layui-progress layui-progress-big" lay-showPercent="yes" lay-filter="filter-demo">
<div class="layui-progress-bar" lay-percent=""></div>
</div>
</div>
<hr style="margin: 21px 0;">
<div class="layui-upload">
<button type="button" class="layui-btn" id="ID-upload-demo-btn-2">
<i class="layui-icon layui-icon-upload"></i> 多图片上传
</button>
<blockquote class="layui-elem-quote layui-quote-nm" style="margin-top: 11px;">
预览图:
<div class="layui-upload-list" id="upload-demo-preview"></div>
</blockquote>
</div>
<!-- import layui -->
<script>
layui.use(function(){
var upload = layui.upload;
var layer = layui.layer;
var element = layui.element;
var $ = layui.$;
// 单图片上传
var uploadInst = upload.render({
elem: '#ID-upload-demo-btn',
url: 'https://httpbin.org/post', // 此处用的是第三方的 http 请求演示,实际使用时改成您自己的上传接口即可。
before: function(obj){
// 预读本地文件示例不支持ie8
obj.preview(function(index, file, result){
$('#ID-upload-demo-img').attr('src', result); // 图片链接base64
});
element.progress('filter-demo', '0%'); // 进度条复位
layer.msg('上传中', {icon: 16, time: 0});
},
done: function(res){
// 若上传失败
if(res.code > 0){
return layer.msg('上传失败');
}
// 上传成功的一些操作
// …
$('#ID-upload-demo-text').html(''); // 置空上传失败的状态
},
error: function(){
// 演示失败状态,并实现重传
var demoText = $('#ID-upload-demo-text');
demoText.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-xs demo-reload">重试</a>');
demoText.find('.demo-reload').on('click', function(){
uploadInst.upload();
});
},
// 进度条
progress: function(n, elem, e){
element.progress('filter-demo', n + '%'); // 可配合 layui 进度条元素使用
if(n == 100){
layer.msg('上传完毕', {icon: 1});
}
}
});
// 多图片上传
upload.render({
elem: '#ID-upload-demo-btn-2',
url: 'https://httpbin.org/post', // 此处用的是第三方的 http 请求演示,实际使用时改成您自己的上传接口即可。
multiple: true,
before: function(obj){
// 预读本地文件示例不支持ie8
obj.preview(function(index, file, result){
$('#upload-demo-preview').append('<img src="'+ result +'" alt="'+ file.name +'" style="width: 90px; height: 90px;">')
});
},
done: function(res){
// 上传完毕
// …
}
});
});

View File

@@ -0,0 +1,25 @@
<button type="button" class="layui-btn layui-btn-danger" id="ID-upload-demo-size">
<i class="layui-icon layui-icon-upload"></i> 上传图片
</button>
<div class="layui-inline layui-word-aux">
这里以限制 60KB 为例
</div>
<!-- import layui -->
<script>
layui.use(function(){
var upload = layui.upload;
var layer = layui.layer;
// 渲染
upload.render({
elem: '#ID-upload-demo-size',
url: '', // 此处配置你自己的上传接口即可
size: 60, // 限制文件大小,单位 KB
done: function(res){
layer.msg('上传成功');
console.log(res);
}
});
});
</script>

View File

@@ -0,0 +1,127 @@
---
title: 上传组件 upload
toc: true
---
# 上传组件
> 上传组件 `upload` 是用于处理文件上传的前端交互逻辑,可以更好地协助后端实现文件从本地到服务端上传的对接。
<h2 id="examples" lay-toc="{hot: true, anchor: null}" style="margin-bottom: 0;">示例</h2>
以下示例的部分上传接口由第三方网站 `https://httpbin.org` 提供,它可以模拟各类 HTTP 请求。若未配置上传接口的,每次上传都会报「请求上传接口出现异常」的提示,这属于正常现象。
<div class="ws-docs-showcase"></div>
<div>
{{- d.include("/upload/detail/demo.md") }}
</div>
<p></p>
<h2 id="api" lay-toc="{hot: true}">API</h2>
| API | 描述 |
| --- | --- |
| var upload = layui.upload | 获得 `upload` 模块。 |
| [var inst = upload.render(options)](#render) | upload 组件渲染,核心方法。 |
| [inst.upload()](#upload) | 对当前实例提交上传 |
| [inst.reload(options)](#reload) | 对当前实例进行重载 |
| inst.config | 获得当前实例的属性配置项 |
<h3 id="render" lay-toc="{level: 2, hot: true}">渲染</h3>
`upload.render(options);`
- 参数 `options` : 基础属性配置项。[#详见属性](#options)
<br>注 : 除 `elem` 属性外,其他基础属性也可以直接写在元素的 `lay-options="{}"` 属性中。
```
<button type="button" class="layui-btn" id="ID-test-uoload">上传</button>
<button type="button" class="layui-btn test-class-upload" lay-options="{}">上传</button>
<button type="button" class="layui-btn test-class-upload" lay-options="{}">上传</button>
<!-- import layui -->
<script>
layui.use(function(){
var upload = layui.upload;
// 单个渲染
upload.render({
elem: '#ID-test-uoload',
// …
});
// 批量渲染
upload.render({
elem: '.test-class-upload',
// …
});
});
</script>
```
该方法返回一个实例对象,包含操作当前实例的相关方法成员。
```
var inst = upload.render(options);
console.log(inst); // 得到当前实例对象
```
<h3 id="upload" lay-toc="{level: 2}">提交上传</h3>
`inst.upload();`
- 无需传递参数
文件在进行选择后,会自动提交上传。而若文件*上传失败*,则可以使用该方法来重新上传,
```
// 渲染
var inst = upload.render({
elem: '#id',
error: function(){ // 上传失败的回调
// 当上传失败时,可在此处生成「重新上传」按钮,并执行该方法重新触发上传提交
/*
$('#btn').on('click', function(){
inst.upload();
})
*/
}
// …
});
```
<h3 id="reload" lay-toc="{level: 2}">重载</h3>
`inst.reload(options);`
- 参数 `options` : 基础属性配置项。[#详见属性](#options)
该方法用于对当前的上传实例进行完整重载,所有属性均可参与到重载中。
```
// 渲染
var inst = upload.render({
elem: '#id',
// …
});
// 重载
inst.reload({
field: 'AAA',
// …
})
```
<h3 id="options" lay-toc="{level: 2, hot: true}">属性</h3>
<div>
{{- d.include("/upload/detail/options.md") }}
</div>
<h2 id="cors-upload" lay-toc="{}">跨域方案</h2>
`upload` 组件支持跨域上传,一般有以下两种场景
- 自建上传服务。在服务端配置 `CORS` 开启跨资源共享。 即对接口所在的服务器设置 `Access-Control-Allow-Origin ` 相关 `header` 信息。
- 第三方上传服务。如:阿里云、腾讯云等,只需按照不同平台对应的上传 SDK 进行操作即可。