向 tornado Web 服务器上传多个文件

以下 html 代码可用于创建允许一次上传多个文件的 html 表单:

upload_form.html
<form enctype="multipart/form-data" method="POST" action="upload.py">
  <table style="width: 100%">
    <tr>
      <td>Choose the files to upload:</td>
      <td style="text-align: right"><input type="file" multiple="" id="files" name="files"></td>
    </tr>
    <tr>
      <td><input id="fileUploadButton" type="submit" value="Upload >>"></td>
      <td></td>
    </tr>
  </table>
</form>

使用 tornado Web 服务器,可以用类似这样的代码处理包含未知数量文件的传入请求:

tornado_upload.py
class UploadFile(tornado.web.RequestHandler):
  # 处理 post 请求
  def post(self):
    # ... 也许添加一个检查用户是否被允许上传任何内容的检查 ...
    # 应该上传的文件
    files = []
    # 检查请求是否包含应该上传的文件
    try:
      files = self.request.files['files']
    except:
      pass
    # 对于每个应该上传的文件
    for xfile in files:
      # 获取默认文件名
      file = xfile['filename']
      # 文件名不应包含任何"恶意"特殊字符
      # 基本上"恶意"字符是所有允许你从上传目录中跳出的字符
      index = file.rfind(".")
      filename = file[:index].replace(".", "") + str(time.time()).replace(".", "") + file[index:]
      filename = filename.replace("/", "")
      # 将文件保存在上传文件夹中
      with open("uploads/%s" % (filename), "w") as out:
        # 请注意,用户可能上传了恶意内容如可执行脚本...
        # 所以在保存文件之前检查文件内容 (xfile['body']) 是个好主意
        out.write(xfile['body'])

请记住,tornado Web 服务器将完整的 html 请求存储在 RAM 中 - 如果多个用户同时上传大文件,这对 Web 服务器来说可能太多了。所以你可能需要限制最大上传大小。如果你将 nginx Web 服务器与 tornado 结合使用,你可以在 nginx 配置文件中限制最大上传大小:

nginx_upload.conf
# ...
http {
    # ...
    client_max_body_size 100m; # 值为 0 禁用 max_body_size 检查 ...
    # ...
}

Check out similar posts by category: Python