我正在研究一种个人云项目,该项目允许上传和下载文件(具有类似Google的搜索功能)。当我使用react.js网站作为客户端时,后端是用python(使用aiohttp)编写的。上传文件后,后端会将其存储在文件系统中,并使用sha256哈希对其进行重命名。原始名称和其他一些元数据存储在其旁边(描述等)。当用户下载文件时,我使用多部分方式提供文件,并且希望用户使用原始名称而不是哈希来获取文件,实际上my-cool-image.png
比a14e0414-b84c-4d7b-b0d4-49619b9edd8a
更易于使用。但是我无法做到(无论我如何尝试,下载文件都用哈希值调用)。
这是我的代码:
async def download(self, request):
if not request.username:
raise exceptions.Unauthorized("A valid token is needed")
data = await request.post()
hash = data["hash"]
file_path = storage.get_file(hash)
dotfile_path = storage.get_file("." + hash)
if not os.path.exists(file_path) or not os.path.exists(dotfile_path):
raise exceptions.NotFound("file <{}> does not exist".format(hash))
with open(dotfile_path) as dotfile:
dotfile_content = json.load(dotfile)
name = dotfile_content["name"]
headers = {
"Content-Type": "application/octet-stream; charset=binary",
"Content-Disposition": "attachment; filename*=UTF-8''{}".format(
urllib.parse.quote(name, safe="")
),
}
return web.Response(body=self._file_sender(file_path), headers=headers)
尽管我想澄清一件事:有时我(在客户端)收到警告,说Resource interpreted as Document but transferred with MIME type application/octet-stream
。我不知道文件的MIME类型,因为它们是由用户提供的,但是我尝试使用image / png(我对存储在服务器上的png图像进行了测试)。该文件未下载(已显示在浏览器中,这不是我想要的东西),并且该文件名仍是其哈希值,因此对我的问题没有帮助。
这是后端的完整源代码:https://git.io/nexmind-node和前端:https://git.io/nexmind-client
编辑:我收到了朱利安·卡斯蒂欧(Julien Castiaux)的第一个答复,所以我尝试实现它,即使它看起来更好,也不能解决我的问题(我仍然有完全相同的行为):]
async def download(self, request):
if not request.username:
raise exceptions.Unauthorized("A valid token is needed")
data = await request.post()
hash = data["hash"]
file_path = storage.get_file(hash)
dotfile_path = storage.get_file("." + hash)
if not os.path.exists(file_path) or not os.path.exists(dotfile_path):
raise exceptions.NotFound("file <{}> does not exist".format(hash))
with open(dotfile_path) as dotfile:
dotfile_content = json.load(dotfile)
name = dotfile_content["name"]
response = web.StreamResponse()
response.headers['Content-Type'] = 'application/octet-stream'
response.headers['Content-Disposition'] = "attachment; filename*=UTF-8''{}".format(
urllib.parse.quote(name, safe="") # replace with the filename
)
response.enable_chunked_encoding()
await response.prepare(request)
with open(file_path, 'rb') as fd: # replace with the path
for chunk in iter(lambda: fd.read(1024), b""):
await response.write(chunk)
await response.write_eof()
return response
我正在研究一种个人云项目,该项目允许上传和下载文件(具有类似Google的搜索功能)。后端是用python(使用aiohttp)编写的,而我正在使用react ....
摘自aiohttp3文档