将ajax中的文件上传到CherryPy

时间:2014-11-11 23:41:50

标签: python ajax upload cherrypy

我正在尝试将多个文件一次上传到CherryPy服务器。

我关注的是显示服务器端PHP代码的this tutorial

JavaScript部分很简单。以下是它的作用摘要:

function FileSelectHandler(e) {
  var files = e.target.files || e.dataTransfer.files;
  for (var i = 0, f; f = files[i]; i++) {
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "upload", true);
    xhr.setRequestHeader("X_FILENAME", file.name);
    xhr.send(file);
}

我将教程中描述的upload.php翻译成如下:

def upload(self):
    [...]

当服务器收到请求时,我可以看到cherrypy.request.headers['Content-Length'] == 5676 这是我试图上传的文件的长度,所以我假设整个文件已经发送到服务器。

如何获取文件内容?

1 个答案:

答案 0 :(得分:2)

至少它看起来如下。在Firefox和Chromium中测试过。如果您需要支持旧版浏览器,我会查看一些JavaScript库以进行polyfill和后备。

#!/usr/bin/env python
# -*- coding: utf-8 -*-


import os
import shutil

import cherrypy


config = {
  'global' : {
    'server.socket_host' : '127.0.0.1',
    'server.socket_port' : 8080,
    'server.thread_pool' : 8,
  }
}


class App:

  @cherrypy.expose
  def index(self):
    return '''<!DOCTYPE html>
      <html>
      <head>
        <title>CherryPy Async Upload</title>
      </head>
      <body>
        <form id='upload' action=''>
          <label for='fileselect'>Files to upload:</label>
          <input type='file' id='fileselect' multiple='multiple' />
        </form>
        <script type='text/javascript'>
          function upload(file)
          {
            var xhr = new XMLHttpRequest();

            xhr.upload.addEventListener('progress', function(event) 
            {
              console.log('progess', file.name, event.loaded, event.total);
            });
            xhr.addEventListener('readystatechange', function(event) 
            {
              console.log(
                'ready state', 
                file.name, 
                xhr.readyState, 
                xhr.readyState == 4 && xhr.status
              );
            });

            xhr.open('POST', '/upload', true);
            xhr.setRequestHeader('X-Filename', file.name);

            console.log('sending', file.name, file);
            xhr.send(file);
          }

          var select = document.getElementById('fileselect');
          var form   = document.getElementById('upload')
          select.addEventListener('change', function(event)
          {
            for(var i = 0; i < event.target.files.length; i += 1)
            {
              upload(event.target.files[i]); 
            }
            form.reset();
          });
        </script>
      </body>
      </html>
   '''

  @cherrypy.expose
  def upload(self):
    '''Handle non-multipart upload'''

    filename    = os.path.basename(cherrypy.request.headers['x-filename'])
    destination = os.path.join('/home/user', filename)
    with open(destination, 'wb') as f:
      shutil.copyfileobj(cherrypy.request.body, f)


if __name__ == '__main__':
  cherrypy.quickstart(App(), '/', config)