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即可。  注意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     })

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章