用Python创建文件分享网站

4 投票
2 回答
3764 浏览
提问于 2025-04-15 23:06

我想设计一个简单的网站,让一个人可以上传文件,然后把随机生成的网页地址给别人,后者就可以下载这个文件。

目前,我已经有了一个网页,用户可以在上面成功上传文件,这些文件会存储在我的网络服务器的 /files/ 文件夹下。

这个Python脚本还会生成一个独特的、随机的5个字母的代码,这个代码会存储在数据库中,用来标识这个文件。

我还有一个叫做“retrieve”的页面,用户应该去这个页面,输入5个字母的代码,然后应该会弹出一个文件框,询问用户要把文件保存到哪里。

我现在遇到的问题是:1)我该如何让用户下载文件?目前我的retrieve脚本可以获取代码,并找到服务器上文件的位置,但我该如何让浏览器开始下载呢?

2)我该如何防止别人直接访问文件?我需要更改文件的权限吗?

2 个回答

0

你需要发送正确的HTTP响应,这样才能包含二进制数据,并让浏览器对此做出反应。

如果你在使用Django,可以试试这个方法(我还没试过):

response = HttpResponse()
response['X-Sendfile'] = os.path.join(settings.MEDIA_ROOT, file.file.path)
content_type, encoding = mimetypes.guess_type(file.file.read())            
if not content_type:
    content_type = 'application/octet-stream'            
response['Content-Type'] = content_type            
response['Content-Length'] = file.file.size            
response['Content-Disposition'] = 'attachment; filename="%s"' % file.file.name
return response

来源:http://www.chicagodjango.com/blog/permission-based-file-serving/

2

你是怎么提供文件上传页面的?用户又是怎么上传文件的?
如果你使用的是Python自带的HTTP服务器模块,那你应该不会遇到什么问题。
总之,这里是用Python自带模块处理文件服务的基本思路。

关于你的第二个问题,如果你一开始就使用这些模块,你可能就不会问这个问题了,因为你需要明确地提供特定的文件。

import SocketServer
import BaseHTTPServer


class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):

    def do_GET(self):
        # The URL the client requested
        print self.path

        # analyze self.path, map the local file location...

        # open the file, load the data
        with open('test.py') as f: data = f.read()

        # send the headers
        self.send_response(200)
        self.send_header('Content-type', 'application/octet-stream') # you may change the content type
        self.end_headers()
        # If the file is not found, send error code 404 instead of 200 and display a message accordingly, as you wish.

        # wfile is a file-like object. writing data to it will send it to the client
        self.wfile.write(data)

        # XXX: Obviously, you might want to send the file in segments instead of loading it as a whole


if __name__ == '__main__':

    PORT = 8080 # XXX

    try:
        server = SocketServer.ThreadingTCPServer(('', 8080), RequestHandler)
        server.serve_forever()
    except KeyboardInterrupt:
        server.socket.close()

撰写回答