var config = {// Tencent Cloudのキーを取得します。権限が限定されたサブアカウントのキーを使用することを推奨します https://console.tencentcloud.com/cam/capisecretId: process.env.COS_SECRET_ID,secretKey: process.env.COS_SECRET_KEY,// キーの有効期間durationSeconds: 1800,// ここにバケットとリージョンを入力します。例:test-1250000000、ap-guangzhoubucket: process.env.PERSIST_BUCKET,region: process.env.PERSIST_BUCKET_REGION,// アップロードが制限されるサフィックスextWhiteList: ['jpg', 'jpeg', 'png', 'gif', 'bmp'],};
npm install
node app.js
/// ダイレクトアップロードのURLや署名などを取得します/// @param ext ファイルのサフィックス。ダイレクトアップロードすると、バックエンドはサフィックスに基づいてCOSキーを生成します/// @return ダイレクトアップロード用のURLや署名などstatic Future<Map<String, dynamic>> getStsDirectSign(String ext) async {Dio dio = Dio();//ダイレクトアップロード署名サービスのURL(本番環境では、正規のダイレクトアップロード署名サービスURLに置き換えてください)//ダイレクトアップロード署名サービスのサーバーコード例はこちらを参考:https://github.com/tencentyun/cos-demo/blob/main/server/direct-sign/nodejs/app.js//10.91.22.16はダイレクトアップロード署名サービスのサーバーアドレスです。例えば上記のnodeサービスなど、要するに、ダイレクトアップロード署名サービスサーバーにアクセスするためのURLですResponse response = await dio.get('http://10.91.22.16:3000/sts-direct-sign',queryParameters: {'ext': ext});if (response.statusCode == 200) {if (kDebugMode) {print(response.data);}if (response.data['code'] == 0) {return response.data['data'];} else {throw Exception('getStsDirectSign error code: ${response.data['code']}, error message: ${response.data['message']}');}} else {throw Exception('getStsDirectSign HTTP error code: ${response.statusCode}');}}
/// ファイルをアップロード/// @param filePath ファイルパス/// @param progressCallback 進捗コールバックstatic Future<void> upload(String filePath, ProgressCallback progressCallback) async {String ext = path.extension(filePath).substring(1);Map<String, dynamic> directTransferData;try {directTransferData = await getStsDirectSign(ext);} catch (err) {if (kDebugMode) {print(err);}throw Exception("getStsDirectSign fail");}String cosHost = directTransferData['cosHost'];String cosKey = directTransferData['cosKey'];String authorization = directTransferData['authorization'];String securityToken = directTransferData['securityToken'];String url = 'https://$cosHost/$cosKey';File file = File(filePath);Options options = Options(method: 'PUT',headers: {'Content-Length': await file.length(),'Content-Type': 'application/octet-stream','Authorization': authorization,'x-cos-security-token': securityToken,'Host': cosHost,},);try {Dio dio = Dio();Response response = await dio.put(url,data: file.openRead(),options: options, onSendProgress: (int sent, int total) {double progress = sent / total;if (kDebugMode) {print('Progress: ${progress.toStringAsFixed(2)}');}progressCallback(sent, total);});if (response.statusCode == 200) {if (kDebugMode) {print('アップロードしました');}} else {throw Exception("アップロードに失敗しました ${response.statusMessage}");}} catch (error) {if (kDebugMode) {print('Error: $error');}throw Exception("アップロードに失敗しました ${error.toString()}");}}
/// ダイレクトアップロード用のURLと署名などを取得します/// @param ext ファイルのサフィックス。ダイレクトアップロードすると、バックエンドは拡張子に基づいてCOSキーを生成します/// @return ダイレクトアップロード用のURLと署名などstatic Future<Map<String, dynamic>> _getStsDirectSign(String ext) async {HttpClient httpClient = HttpClient();//ダイレクトアップロード署名サービスのサーバーURL(本番環境では、正規のダイレクトアップロード署名サービスURLに置き換えてください)//ダイレクトアップロード署名サービスのサーバーコード例はこちらを参考:https://github.com/tencentyun/cos-demo/blob/main/server/direct-sign/nodejs/app.js//10.91.22.16はダイレクトアップロード署名サービスのサーバーアドレスです。例えば上記のnodeサービスなど、要するに、ダイレクトアップロード署名サービスサーバーにアクセスするためのURLですHttpClientRequest request = await httpClient.getUrl(Uri.parse("http://10.91.22.16:3000/sts-direct-sign?ext=$ext"));HttpClientResponse response = await request.close();String responseBody = await response.transform(utf8.decoder).join();if (response.statusCode == 200) {Map<String, dynamic> json = jsonDecode(responseBody);if (kDebugMode) {print(json);}httpClient.close();if (json['code'] == 0) {return json['data'];} else {throw Exception('getStsDirectSign error code: ${json['code']}, error message: ${json['message']}');}} else {httpClient.close();throw Exception('getStsDirectSign HTTP error code: ${response.statusCode}');}}
/// ファイルをアップロード/// @param filePath ファイルパス/// @param progressCallback 進捗コールバックstatic Future<void> upload(String filePath, ProgressCallback progressCallback) async {// ダイレクトアップロードの署名情報などを取得String ext = path.extension(filePath).substring(1);Map<String, dynamic> directTransferData;try {directTransferData = await _getStsDirectSign(ext);} catch (err) {if (kDebugMode) {print(err);}throw Exception("getStsDirectSign fail");}String cosHost = directTransferData['cosHost'];String cosKey = directTransferData['cosKey'];String authorization = directTransferData['authorization'];String securityToken = directTransferData['securityToken'];String url = 'https://$cosHost/$cosKey';File file = File(filePath);int fileSize = await file.length();HttpClient httpClient = HttpClient();HttpClientRequest request = await httpClient.putUrl(Uri.parse(url));request.headers.set('Content-Type', 'application/octet-stream');request.headers.set('Content-Length', fileSize.toString());request.headers.set('Authorization', authorization);request.headers.set('x-cos-security-token', securityToken);request.headers.set('Host', cosHost);request.contentLength = fileSize;Stream<List<int>> stream = file.openRead();int bytesSent = 0;stream.listen((List<int> chunk) {bytesSent += chunk.length;double progress = bytesSent / fileSize;if (kDebugMode) {print('Progress: ${progress.toStringAsFixed(2)}');}progressCallback(bytesSent, fileSize);request.add(chunk);},onDone: () async {HttpClientResponse response = await request.close();if (response.statusCode == 200) {if (kDebugMode) {print('アップロードしました');}} else {throw Exception("アップロードに失敗しました $response");}},onError: (error) {if (kDebugMode) {print('Error: $error');}throw Exception("アップロードに失敗しました ${error.toString()}");},cancelOnError: true,);}
フィードバック