简体   繁体   中英

Django FileResponse Content-Disposition header not working for filename

I use the Content-Disposition header because the stored name of the files is different from the name they are served. But header not working in all files correctly, i'm directly passing filename to header. Filenames contains non-ASCII characters.

Here is the download view i'm using:

@api_view(['GET'])
def download_streamer(request, **kwargs):
    dlo = DownloadLink.objects.get(token=kwargs['token'])
    if dlo.is_expired:
        return Response({'link_expired': 'Download link expired, try again'},
                        status=status.HTTP_410_GONE)
    else:
        mimetype, _ = mimetypes.guess_type(dlo.file_cache.stored_at)
        f_response = FileResponse(open(dlo.file_cache.stored_at, 'rb'), content_type=mimetype)
        f_response['Content-Disposition'] = f'attachment; filename={dlo.file_cache.origin.name}'
        f_response['Access-Control-Expose-Headers'] = 'Content-Disposition'
        FileActivity.objects.create(subject=dlo.file_cache.origin, action='GET', user=dlo.owner)
        return f_response

Here is the valid response header which i want (file name not containing non-ASCII chars)

content-disposition: attachment; filename=jinekolojik aciller.ppt

But some files gives this headers (original filename: türkiyede sağlık politikaları.pdf)

content-disposition: =?utf-8?q?attachment=3B_filename=3Dt=C3=BCrkiyede_sa=C4=9Fl=C4=B1k_politikalar=C4=B1=2Epdf?=

I've found a solution for this.

I noticed that when name contains any non legal character response's 'Content Disposition' guess messed up and the browser cannot get the file name out of it.

solution for me was

from django.utils.text import slugify

@api_view(['GET'])
def download_streamer(request, **kwargs):
    dlo = DownloadLink.objects.get(token=kwargs['token'])
    if dlo.is_expired:
        return Response({'link_expired': 'Download link expired, try again'},
                        status=status.HTTP_410_GONE)
    else:
        mimetype, _ = mimetypes.guess_type(dlo.file_cache.stored_at)
        f_response = FileResponse(open(dlo.file_cache.stored_at, 'rb'), content_type=mimetype)
        f_response['Content-Disposition'] = f'attachment; filename={slugify(dlo.file_cache.origin.name)}'
        f_response['Access-Control-Expose-Headers'] = 'Content-Disposition'
        FileActivity.objects.create(subject=dlo.file_cache.origin, action='GET', user=dlo.owner)
        return f_response

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM