世界上最伟大的投资就是投资自己的教育
ant design pro 如何使用阿里云直传的上传组件
随风发布于860 次阅读
如上图所示,
我们上传图片或文件到后端时,有两种方式
一种是直传到后端,另一种是用 oss 自带的 api
第一种会带我们自己的服务器带来消耗,假如你上传 1 G 的文件,这个时候你要带宽要比较大才顶得住。
如果用直传,就跟我们服务器没关了。
直传到阿里云,最后拿到它返回的地址,传到我们的自己数据库即可。
前端
组件我写好了
<AliyunOSSUpload
onFileUpload={(url: string) => {
console.log('Uploaded file URL:', url);
setImageUrl!(url);
}}
accept=".jpg,.jpeg,.png,.pdf"
defaultFileList={defaultFileList}
/>
源码在此:
import React, { useEffect, useState } from 'react';
import { InboxOutlined } from '@ant-design/icons';
import type { UploadFile, UploadProps } from 'antd';
import { message, Upload } from 'antd';
import { FormattedMessage, request } from '@umijs/max';
interface OSSDataType {
dir: string;
expire: string;
host: string;
accessId: string;
policy: string;
signature: string;
}
interface AliyunOSSUploadProps {
value?: UploadFile[];
onChange?: (fileList: UploadFile[]) => void;
accept?: string;
onFileUpload: (url: string) => void;
defaultFileList?: any;
}
const defaultAccept = '*';
const AliyunOSSUpload = ({
value,
onChange,
accept,
defaultFileList,
onFileUpload,
}: AliyunOSSUploadProps) => {
const [OSSData, setOSSData] = useState<OSSDataType>();
// Fetch OSS Data from Backend API
const fetchOSSData = async () => {
try {
const data = await request('/upload/get-oss-credentials'); // Adjust the endpoint as necessary
setOSSData(data);
} catch (error: any) {
message.error(`Failed to get OSS data: ${error.message}`);
}
};
useEffect(() => {
fetchOSSData();
}, []);
const handleChange: UploadProps['onChange'] = ({ fileList }) => {
console.log('Aliyun OSS:', fileList);
if (fileList?.length > 0) {
const lastFile = fileList[fileList.length - 1]; // 获取最后一个文件对象
const lastFileUrl = lastFile.url;
onFileUpload(lastFileUrl!);
}
onChange?.([...fileList]);
};
const onRemove = (file: UploadFile) => {
const files = (value || []).filter((v) => v.url !== file.url);
onChange?.(files);
};
const getExtraData: UploadProps['data'] = (file) => ({
key: file.url,
OSSAccessKeyId: OSSData?.accessId,
policy: OSSData?.policy,
Signature: OSSData?.signature,
});
const beforeUpload: UploadProps['beforeUpload'] = async (file: any) => {
if (!OSSData) return false;
const expire = Number(OSSData.expire) * 1000;
if (expire < Date.now()) {
await fetchOSSData();
}
const suffix = file.name.slice(file.name.lastIndexOf('.'));
const filename = Date.now() + suffix;
file.url = OSSData?.dir + filename; // Update file url to include the directory
return file;
};
const uploadProps: UploadProps = {
name: 'file',
fileList: value,
action: OSSData?.host,
onChange: handleChange,
onRemove,
accept: accept || defaultAccept,
data: getExtraData,
beforeUpload,
};
return (
<Upload.Dragger
{...uploadProps}
listType="picture"
showUploadList={{ showRemoveIcon: true }}
maxCount={1}
style={{ width: 328 }}
defaultFileList={defaultFileList}
>
<p className="ant-upload-drag-icon">
<InboxOutlined />
</p>
<p className="ant-upload-text">
<FormattedMessage
id="upload_text"
defaultMessage="Click or drag file to this area to upload"
/>
</p>
</Upload.Dragger>
);
};
export default AliyunOSSUpload;
后端
后端只要获取 oss 的一些凭证就可以了
export const getOssCredentials = handleAsync(async (req: Request, res: Response) => {
// Set the policy expiration time
const policy = {
expiration: new Date(new Date().getTime() + 60 * 60 * 1000).toISOString(), // Expires in 30 minutes
conditions: [
['content-length-range', 0, 1048576000], // Limit upload size to no more than 1000MB
]
};
const result = await ossClient.calculatePostSignature(policy) as any;
const host = `https://${process.env.OSS_BUCKET}.oss-cn-hongkong.aliyuncs.com`;
res.json({
accessId: process.env.OSS_ACCESS_KEY_ID,
policy: result.policy,
signature: result.Signature,
host,
dir: 'user-dir/',
expire: new Date().getTime() + 30 * 60 * 1000, // Front-end use expiration time (milliseconds)
});
})
本站文章均为原创内容,如需转载请注明出处,谢谢。
0 条回复
暂无回复~~
© 汕尾市求知科技有限公司 | Rails365 Gitlab | 知乎 | b 站 | csdn
粤公网安备 44152102000088号 | 粤ICP备19038915号
Top