# 文件上传下载功能
当在 api 中的传入参数中使用了$file.file
引用符,yao 框架会把上传的文件保存成临时文件。并返回一个文件数据结构为 UploadFile 的对象。
这个第二个.file
就是在文件上传时的的元数据中的name
。
通常来说,在浏览器上传时的请求格式是这样的,其中的name="file"
就对应上面的$file.file
,如果是其它类型的,就使用不同的name
进行引用。比如其它的像image
,video
。
txt
------WebKitFormBoundaryyNSuPN4V37SH3V5y
Content-Disposition: form-data; name="file"; filename="baner01.png"
Content-Type: image/png
------WebKitFormBoundaryyNSuPN4V37SH3V5y--
当文件上传到服务器后,文件会先存在在一个服务器的临时目录,比如说 linux 下是/temp
目录。并且文件名会是生成的唯一名称。并且返回一个描述文件信息的对象。
json
{
"name": "文件名",
"tempFile": "临时文件名",
"size": "文件大小",
"mimeType": "文件类型"
}
go
type UploadFile struct {
Name string `json:"name"`
TempFile string `json:"tempFile"`
Size int64 `json:"size"`
Header textproto.MIMEHeader `json:"mimeType"`
}
在 apis 目录定义一个新的文件上传下载接口:
json
{
"name": "存储接口",
"version": "1.0.0",
"description": "存储接口API",
"group": "storage",
"guard": "bearer-jwt",
"paths": [
{
"path": "/upload",
"method": "POST",
"process": "fs.system.Upload",
"in": ["$file.file"],
"out": {
"status": 200,
"type": "application/json"
}
},
{
"path": "/download",
"method": "GET",
"guard": "-",
"process": "fs.system.Download",
"in": ["$query.name"],
"out": {
"status": 200,
"body": "{{content}}",
"headers": { "Content-Type": "{{type}}" }
}
}
]
}
文件处理器
yao 内置了几个与文件上传下载相关的处理器:
fs.system.Upload,把文件从临时目录写入到应用目录下,并以当天的目录创建一个子目录,并返回文件名,这个文件名也是一个自动生成的唯一的文件名。
fs.system.Download,读取应用目录下的文件,并通过 http 接口返回。文件的 mime 信息会自动根据文件进行判断。这个接口会返回以下的消息,需要注意的是 mimetype 并不是上传的类型,因为并没有保存到数据库中,只是根据文件本身的信息头作判断,有可能会有误差。
json{ "content": "文件内容", "type": "mime-type" }
另外也可以使用 js 函数自定义文件上传功能。
js
//scripts.file.upload
function upload(file) {
// "map[mimeType:map[Content-Disposition:[form-data; name=\"file\"; filename=\"blob\"]
// Content-Type:[image/png]] name:blob size:108505
// tempFile:C:\\Users\\USER\\AppData\\Local\\Temp\\upload2241272960\\file-2567307823]"
// 这里不能直接使用处理器fs.system.Upload,因为经过js桥接后,数据结构已经变化。
// https://github.com/wwsheng009/gou/commit/7fafef2100057343024e6fbe7728fd7d58cb28c9
// 读取临时文件
const f = Process('fs.system.ReadFile', file.tempFile);
const ts = Process('utils.now.Timestampms');
// 自定义文件路径
const fn = `/data/${ts}`;
// 写入文件
Process('fs.system.WriteFile', fn, f, '0644');
// 返回文件下载地址,这个地址也可以自定义,需要配合api中的下载地址定义
return `/yao-api/download?name=${fn}`;
}
下载地址:
sh
http://dev.com:5099/yao-api/download?name=test.png
文件下载测试页面。
html
<!DOCTYPE html>
<html>
<head>
<title>Download PNG File Example</title>
</head>
<body>
<h1>Download PNG File Example</h1>
<p>Click the link below to download a PNG file in a new window:</p>
<a
href="http://dev.com:5099/yao-api/download?name=test.png"
download
target="_blank"
>Download PNG File</a
>
</body>
</html>