2008-11-04 52 views
9

Tôi đang viết ngân hàng hình ảnh với Django và tôi muốn thêm nút để có phiên bản có độ phân giải cao của hình ảnh (độ phân giải thấp được hiển thị trong trang chi tiết) . Nếu tôi chỉ đặt liên kết <a>, trình duyệt sẽ mở hình ảnh thay vì tải xuống. Thêm tiêu đề HTTP như:tiêu đề HTTP tùy chỉnh cho các tệp tĩnh với Django

Content-Disposition: attachment; filename="beach008.jpg" 

hoạt động, nhưng vì đây là tệp tĩnh nên tôi không muốn xử lý yêu cầu với Django. Hiện tại, tôi đang sử dụng NGINX để phục vụ các tệp tĩnh và các trang động được chuyển hướng qua FastCGI đến quá trình Django. Tôi đang nghĩ về việc sử dụng NGINX add-header lệnh, nhưng nó có thể thiết lập một phần filename="xx" ?. Hoặc có thể có một số cách để xử lý yêu cầu trong Django, nhưng làm cho NGINX phục vụ nội dung?

Trả lời

10

Nếu ứng dụng django của bạn được proxy của nginx, bạn có thể sử dụng x-accell-redirect. Bạn cần phải vượt qua một tiêu đề đặc biệt trong phản ứng của bạn, nginx sẽ intercepet này và bắt đầu phục vụ các tập tin, bạn cũng có thể vượt qua Content-Disposition trong cùng một phản ứng để buộc tải xuống.

Giải pháp đó là tốt nếu bạn muốn kiểm soát những người dùng nào có được những tệp này.

Bạn cũng có thể sử dụng cấu hình như thế này:

#files which need to be forced downloads 
    location /static/high_res/ { 
     root /project_root; 

     #don't ever send $request_filename in your response, it will expose your dir struct, use a quick regex hack to find just the filename 
     if ($request_filename ~* ^.*?/([^/]*?)$) 
     { 
      set $filename $1; 
     } 

     if ($filename ~* ^.*?\.(jpg)|(png)|(gif)$){ 
         add_header Content-Disposition "attachment; filename=$filename"; 
        } 
     } 

    location /static { 
     root /project_root; 
    } 

Điều này sẽ buộc tải trên tất cả các hình ảnh trong một số thư mục high_res (MEDIAROOT/high_rest). Và đối với các tệp tĩnh khác, nó sẽ hoạt động như bình thường. Xin lưu ý rằng đây là một bản hack nhanh được sửa đổi phù hợp với tôi. Nó có thể có các tác động an ninh, vì vậy hãy sử dụng nó để đề phòng.

+0

tuyệt vời! Chính xác những gì tôi đang tìm kiếm. – Javier

+0

Tôi có thiếu thứ gì đó hay không. *? dư thừa? Bạn chỉ có thể sử dụng. * Nếu nó là perl regex. –

4

Tôi đã viết một trang trí đơn giản, cho chế độ xem django.views.static.serve

Làm việc hoàn hảo cho tôi.

def serve_download(view_func): 
    def _wrapped_view_func(request, *args, **kwargs): 
     response = view_func(request, *args, **kwargs) 
     response['Content-Type'] = 'application/octet-stream'; 
     import os.path 
     response['Content-Disposition'] = 'attachment; filename="%s"' % os.path.basename(kwargs['path']) 
     return response 
    return _wrapped_view_func 

Ngoài ra bạn có thể chơi với nginx mime-loại

http://wiki.codemongers.com/NginxHttpCoreModule#types

Giải pháp này không làm việc cho tôi, vì tôi muốn có cả hai liên kết trực tiếp với các tập tin (vì vậy người dùng có thể xem hình ảnh, ví dụ) và liên kết tải xuống.

0

gì tôi đang làm hiện nay là sử dụng một URL khác nhau để tải về hơn cho 'quan điểm', và thêm tên tập tin như một arg URL:

thông thường liên kết truyền thông: http://xx.com/media/images/lores/f_123123.jpg download link: http://xx.com/downs/hires/f_12323?beach008.jpg

và nginx có cấu hình như sau:

location /downs/ { 
     root /var/www/nginx-attachment; 
     add_header Content-Disposition 'attachment; filename="$args"'; 
    } 

nhưng tôi thực sự không thích mùi của nó.

Các vấn đề liên quan