跳到主要内容
版本:4.0.0 🚧

文件上传

Midway Hooks 提供了 @midwayjs/hooks-upload 并配合 @midwayjs/upload 来实现纯函数 + 一体化项目中的文件上传功能。

起步

安装依赖:

npm install @midwayjs/upload @midwayjs/hooks-upload

使用

启用 upload 组件

在后端目录的 configuration.ts 中启用 @midwayjs/upload 组件,具体支持的配置项可查看 文件上传

import { createConfiguration, hooks } from '@midwayjs/hooks';
import * as Koa from '@midwayjs/koa';
+ import * as upload from '@midwayjs/upload';

/**
* setup midway server
*/
export default createConfiguration({
imports: [
Koa,
hooks(),
+ upload
],
importConfigs: [{ default: { keys: 'session_keys' } }],
});

创建接口

在后端目录下,新建接口文件。

import { Api } from '@midwayjs/hooks';
import {
Upload,
useFiles,
} from '@midwayjs/hooks-upload';

export default Api(
Upload('/api/upload'),
async () => {
const files = useFiles();
return files;
}
);

一体化调用

import upload from './api/upload';

function Form() {
const [file, setFile] =
React.useState<FileList>(null);

const handleSubmit = async (
e: React.FormEvent<HTMLFormElement>
) => {
e.preventDefault();
const files = { images: file };
const response = await upload({
files,
});
console.log(response);
};

const handleOnChange = (
e: React.ChangeEvent<HTMLInputElement>
) => {
console.log(e.target.files);
setFile(e.target.files);
};

return (
<form onSubmit={handleSubmit}>
<h1>Hooks File Upload</h1>
<input
multiple
type="file"
onChange={handleOnChange}
/>
<button type="submit">
Upload
</button>
</form>
);
}

手动调用(通过 FormData 上传)

const input =
document.getElementById('file');

const formdata = new FormData();
formdata.append('file', input.files[0]);

fetch('/api/upload', {
method: 'POST',
body: formdata,
})
.then((res) => res.json())
.then((res) => console.log(res));

Api

Upload(path?: string)

声明上传接口,可以指定路径。默认为 POST 接口,只支持 multipart/form-data 类型的请求。

useFiles()

在函数中使用 useFiles() 可以获取上传的文件。返回值为 Object,key 为上传时的字段名。有多个文件字段名相同时,Value 为 Array。

// frontend
await upload({ pdf });

// backend
const files = useFiles();
{
pdf: {
filename: 'test.pdf', // 文件原名
data: '/var/tmp/xxx.pdf', // mode 为 file 时为服务器临时文件地址
fieldname: 'test1', // 表单 field 名
mimeType: 'application/pdf', // mime
}
}

useFields()

返回 FormData 中非文件的字段。

// frontend
const formdata = new FormData();
formdata.append('name', 'test');

post(formdata);

// backend
const fields = useFields();
// { name: 'test' }