Flask与Flutter:无缝上传与显示文件
在现代Web应用中,文件上传和显示功能是常见的需求。本文将介绍如何使用Flask作为后端和Flutter作为前端来实现一个文件上传到Azure Blob Storage并在前端显示的完整流程。
环境准备
首先,我们需要确保以下环境配置:
- Python 3.7+
- Flutter SDK
- Azure存储账户
- 安装必要的Python库:
flask,flask_cors,azure-storage-blob
pip install flask flask_cors azure-storage-blob
Flask后端配置
1. 配置Azure存储
我们首先在Flask中配置Azure Blob Storage的连接:
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient, generate_blob_sas, BlobSasPermissions
connect_str = 'DefaultEndpointsProtocol=CONNECTION_STRING_ETC'
container_name = "documents"
blob_service_client = BlobServiceClient.from_connection_string(conn_str=connect_str)
container_client = blob_service_client.create_container(container_name)
2. 定义上传路由
定义一个上传文件的路由,处理文件上传到Azure Blob Storage:
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return jsonify({"message": "No file available", "status": "fail"}), 400
file = request.files['file']
if file.filename == '':
return jsonify({"message": "No selected file", "status": "fail"}), 400
if file:
timestamp = datetime.now().strftime('%Y-%m-%d_%H:%M:%S')
filename = secure_filename(f"{timestamp}_{file.filename}")
blob_client = container_client.get_blob_client(filename)
blob_client.upload_blob(file.stream, overwrite=True)
file_url = blob_client.url
return jsonify({"message": "File uploaded successfully", "status": "success", "file_url": file_url}), 200
3. 生成SAS Token
为了安全地访问文件,我们使用SAS Token来生成临时URL:
@app.route('/upload/' , methods=['GET'])
def uploaded_file(filename):
blob_client = container_client.get_blob_client(filename)
sas_token = generate_blob_sas(
account_name=blob_service_client.account_name,
container_name=container_name,
blob_name=filename,
account_key=blob_service_client.credential.account_key,
permission=BlobSasPermissions(read=True),
expiry=datetime.now(datetime.UTC) + timedelta(hours=1)
)
signed_url = f"{blob_client.primary_endpoint}/{container_name}/{blob_client.blob_name}?{sas_token}"
return jsonify({"file_url": signed_url, "status": "success"})
Flutter前端实现
1. 接收文件URL
在Flutter中,我们需要从Flask获取文件的URL并显示:
Future<void> fetchFile() async {
setState(() {
isLoading = true;
});
final response = await http.get(Uri.parse('http://127.0.0.1:5000/upload/$filename'));
if (response.statusCode == 200) {
var data = jsonDecode(response.body);
setState(() {
fileUrl = data['file_url'];
isLoading = false;
});
} else {
throw Exception('Failed to load file');
}
}
2. 显示文件
根据文件类型(PDF或图片)选择不同的显示方式:
Widget buildFileWidget() {
if (isLoading) {
return Center(child: CircularProgressIndicator());
} else if (fileUrl != null) {
if (fileUrl!.toLowerCase().endsWith('.pdf')) {
return PDF().cachedFromUrl(fileUrl!);
} else {
return CachedNetworkImage(
imageUrl: fileUrl!,
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
);
}
} else {
return Center(child: Text('File not found'));
}
}
调试与问题解决
- 空白页面问题:检查
fileUrl是否正确接收到了URL,确保Azure存储配置正确,CORS设置正确。 - PDF显示问题:考虑使用
flutter_pdfview或syncfusion_flutter_pdfviewer,注意这些库的平台支持情况。
通过上述步骤,我们可以构建一个功能完备的文件上传和显示系统,利用Flask和Flutter的优势实现跨平台应用的开发。






