如何处理文件并返回给前端
一、概述
打开客户端浏览器下载文件是比较常见的功能,那么后端是如何处理文件的呢?大体解决方法是后端会将文件处理成字节流并返回前端。那么在浏览器访问接口即可自动下载文件(此处是GET请求)
二、FastApi
2.1、下载:
from starlette.responses import StreamingResponse from fastapi.response import FileResponse, Response @app.get("/file") def file(): # 提供一个下载成功后的文件名字 fileName = "xxx.jpg" StreamingHttpResponse将文件内容进行流式传输,数据量大可以用这个方法 response = StreamingResponse(get_file_byte("xxx.jpg"), media_type="application/octet-stream") # 在请求头进行配置 response = response.headers["Content-Disposition"] = "attachment; filename=%s"%fileName return response def get_file_byte(filename, chunk_size=512): # filename可以是文件,也可以是压缩包 with open(filename, "rb") as f: while True: content = f.read(chunk_size) if content: yield content else: break
三、django
3.1、下载
import os from rest_framework import status from django.http import HttpResponse from rest_framework.response import Response from django.utils.encoding import escape_uri_path @action(methods=[GET], detail=False) def download_files(self, request, *args, **kwargs): # fiName = request.query_params.get("file_name") # 辅助参数(?后)数据提取方式 fileName = request.data["file_name"] # 请求体body数据请求方式 base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 项目根目录 file_path = os.path.join(base_dir, upload,images, fileName) # 下载文件的绝对路径 try: # 提供一个下载成功后的文件名字 fileName = "xxx.zip" response = HttpResponse( content = file_iterator(file_path) # 字节流数据 content_type = "application/octet-stream" Content-Disposition = "attachment; filename={}".format(escape_uri_path(fileName)) ) except: return Response({ "code":status.HTTP_400_BAD_REQUEST, "msg":"失败", "error": "Sorry but Not Found the File"}) return response def file_iterator(file_path, chunk_size=512): """ 文件生成器,防止文件过大,导致内存溢出 :param file_path: 文件绝对路径 :param chunk_size: 块大小 :return: 生成器 """ with open(file_path, mode=rb) as f: while True: c = f.read(chunk_size) if c: yield c else: break
3.2、上传
import os from rest_framework.response import Response @action(methods=[POST], detail=False) def upload_file(self, request, *args, **kwargs): try: # 接收数据并处理 data = request.data # 文件上传名字、文件上传路径、文件对象 name, path, fileObj= data["name"], data["path"], request.FILES["file"] # 将传递的文件处理为文件流,进行保存 file = b for byteData in fileObj.chunks(): file += byteData # 写入本地服务器 baseDir = os.path.dirname(os.path.abspath(__name__)); # 项目根目录 jpgDir = os.path.join(baseDir,static,jpg); # 文件保存路径 fileName = os.path.join(jpgDir, name); with open(fileName, "rb") as f: f.write(file) except: return Response({ "code":status.HTTP_400_BAD_REQUEST, "msg":"失败", "error": "Uploading files failed. Procedure"}) return Response({ "code":status.HTTP_200_OK, "msg":"成功")