简体   繁体   English

如何通过 nginx 在 Django 中提供生成的文件作为下载?

[英]How do I serve a generated file in Django via nginx as download?

I'm trying to serve a generated zip file in my media folder via nginx, but I got the following error: open() "/etc/nginx/htmltest.zip" failed (2: No such file or directory)我正在尝试通过 nginx 在我的媒体文件夹中提供生成的 zip 文件,但出现以下错误: open() "/etc/nginx/htmltest.zip" failed (2: No such file or directory)

Somehow nginx is looking for the file in a weirdly malformed "/etc/nginx/html", I don't get why.不知何故,nginx 正在寻找格式奇怪的“/etc/nginx/html”中的文件,我不明白为什么。

I'm using nginx via docker-compose, the code works just fine if I don't use nginx and just run Django in development mode.我正在通过 docker-compose 使用 nginx,如果我不使用 nginx 并在开发模式下运行 ZEF0F9Z1C83E37483766 时,代码就可以正常工作。

folder_path = os.path.join(settings.MEDIA_ROOT, str(uuid.uuid4()))
os.mkdir(folder_path)

shutil.make_archive(os.path.join(folder_path, "test"), 'zip', folder_path, "test")

response = download(os.path.join(folder_path, f"{zip_name}.zip"))


def download(path):
    if os.path.exists(path):

        with open(path, 'rb') as f:
            response = HttpResponse(f.read(), content_type="application/zip")
            response['Content-Disposition'] = 'inline;filename=' + os.path.basename(path)
            response['X-Accel-Redirect'] = os.path.basename(path)
            return response

    raise Http404

My nginx.conf:我的 nginx.conf:

upstream django_app {
    server web:8000;
}

server {

    listen 80;

    location / {
        proxy_pass http://django_app;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
        client_max_body_size 100M;
    }

    location /static/ {
        alias /code/static/;
    }

    location /media/ {
        alias /code/media/;
    }

}

MEDIA_ROOT in settings.py: settings.py 中的 MEDIA_ROOT:

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

You are using nginx X-Accel-Redirect incorrectly.您错误地使用了 nginx X-Accel-Redirect

When using X-Accel-Redirect you do not need to read and send the file from Django yourself, nginx will do it for you.使用X-Accel-Redirect时,您不需要自己从 Django 读取和发送文件,nginx 会为您完成。 That is the whole point of X-Accel-Redirect : offloading file sending from the app server to nginx (which is better at it).这就是X-Accel-Redirect的全部要点:卸载从应用服务器发送的文件到 nginx(它更擅长)。

So remove the X-Accel-Redirect header, then Django will serve the file directly.所以删除X-Accel-Redirect header,然后 Django 将直接提供文件。

If you want to use X-Accel-Redirect then you need to setup nginx as described in the documentation (your config is not complete as it is missing the internal location) and then give the internal URL in the X-Accel-Redirect header (you are incorrectly giving a file system path).如果要使用X-Accel-Redirect ,则需要按照文档中的说明设置 nginx(您的配置不完整,因为它缺少internal位置),然后在X-Accel-Redirect中提供内部URL Z3959FB99E340DB0F3您错误地提供了文件系统路径)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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