Taro 微信小程序 上传文件到minio

小程序前端上传文件不建议直接引用minio的js npm包,一来是这个包本身较大,会影响小程序的体积,二来是ak sk需要放到前端存储,不够安全,因此建议通过请求后端拿到签名数据后上传。

由于小程序的uploadFile仅支持POST请求(估计以后也不会支持PUT了),因此只能使用minio的PresignedPostPolicy方法返回签名后的formData,然后再放到小程序的uploadFile方法的formData参数中

后端 .net

安装minio nuget

接口返回dto

public class UploadInfo 
{
    public string Key { get; set; }    
    public string Url { get; set; }
    public Dictionary<string, string> FormData { get; set; }
}

多个key进行预签名,  注意new  MinioClient的第一个参数是minio的服务器地址,不能有http://或https://, 如果是https则需要new 之后再调用.WithSSL(),参见官方文档。 当然最佳实践还是要将minioClient对象通过依赖注入管理,minio相关配置通过IConfiguration(appsettings.json)来管理。

public async Task<UploadInfo[]> PresignedPostPolicyAsync(string[] keys)
{
    string bucket = "myBucket";
    var minioClient = new MinioClient("myminio.com:9000",
                                           "ak",
                                           "sk"
                                     );
    var result = new UploadInfo[keys.Length];
    for (int i = 0; i < keys.Length; i++)
    {
        var policy = new PostPolicy();
        policy.SetKey(keys[i]);
        policy.SetBucket(bucket);
        policy.SetExpires(DateTime.UtcNow.AddHours(2));//设置策略过期时间
        Tuple<string, Dictionary<string, string>> data = await minioClient.PresignedPostPolicyAsync(policy);
        result[i] = new UploadInfo 
        {
            Key = keys[i],
            Url = $"{data.Item1}{bucket}/{keys[i]}",
            FormData = data.Item2,
        };
    }
    return result;
}

 

后端 java

 

dto

import java.util.Map;
import lombok.Data;

@Data
public class Upload {
    private String key;
    private String url;
    private Map<String, String> formData;
}

 

多个key进行预签名, 和.net sdk不一样的地方在于minio 服务器地址需要加上http, 还有可以设置上传条件,如 addEqualsCondition("key", key),表示key必须为对应的值, addStartsWithCondition("content-type","image/") 表示content-type必须以image/开头,也就是只能上传图片。

public List<Upload> uploadFiles(String[] keys)
            throws IOException, NoSuchAlgorithmException, InvalidKeyException {
        List<Upload> uploads = new ArrayList<>();
        String bucket = "myBucket";
        String endPoint = "http://myminio.com:9000";
        try {
            MinioClient minioClient =
                    MinioClient.builder()
                            .endpoint(endPoint)
                            .credentials("ak", "sk")
                            .build();for (int i = 0; i < jsonArray.size(); i++) {
                Upload upload = new Upload();
                String key = keys[i];
                PostPolicy policy = new PostPolicy(bucket, ZonedDateTime.now().plusHours(2));
                policy.addEqualsCondition("key", key);
                Map<String, String> formData = minioClient.getPresignedPostFormData(policy);
                String url = endPoint + "/" + bucket +"/" + key;
                upload.setKey(key);
                upload.setUrl(url);
                upload.setFormData(formData);
                uploads.add(upload);
            }
        }catch (MinioException e) {
            System.out.println("Error occurred: " + e);
        }
        return uploads;
    }

 

小程序

Taro代码如下,如果是原生微信小程序则把Taro换为wx即可(如原生小程序没有扩展支持async await,则需要更换为wx.request({url:xxx, data:xxx, success=>{ //后续处理 }}))的形式,通过传入success回调来处理拿到预签名数据的情况。  注意uploadFile参数里 name需要设置为file, formData里设置key为policy签名的key。 上传成功minio会返回204

 1     let minioUrl = 'https://myminio.com:9000'
 2     let minioPresignUrl = 'https://myminio.com:8000/files/presign';
 3     Taro.chooseImage({
 4       count: 1,
 5       sizeType: ["original", "compressed"],
 6       sourceType: ["album", "camera"],
 7       success: async res=>{
 8         let result = await Taro.request({url: minioPresignUrl, data: {keys:[res.tempFilePaths[0]]}});
 9         result.data.data.forEach(f => {
10           f.formData.key = f.key;
11           Taro.uploadFile({
12             filePath:res.tempFilePaths[0] ,
13             name: "file",
14             url: minioUrl,
15             formData: f.formData,
16             success: r => {
17                 if (r.statusCode === 204) {
18                     console.log('上传成功');
19                 }
20             }
21         });
22         })
23       }
24     })

 

posted @ 2021-12-13 10:07  turingguo  阅读(2057)  评论(0编辑  收藏  举报