无法使用多部分标题获得正确的文件名

问题描述 投票:0回答:1

我正在研究一种个人云项目,该项目允许上传和下载文件(具有类似Google的搜索功能)。当我使用react.js网站作为客户端时,后端是用python(使用aiohttp)编写的。上传文件后,后端会将其存储在文件系统中,并使用sha256哈希对其进行重命名。原始名称和其他一些元数据存储在其旁边(描述等)。当用户下载文件时,我使用多部分方式提供文件,并且希望用户使用原始名称而不是哈希来获取文件,实际上my-cool-image.pnga14e0414-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)

这是它的外观(根据浏览器):request seen from browser似乎正确,但无法正常工作。

尽管我想澄清一件事:有时我(在客户端)收到警告,说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 ....

python http request multipart aiohttp
1个回答
0
投票

摘自aiohttp3文档

© www.soinside.com 2019 - 2024. All rights reserved.