我试图一次将许多文件上传到我的CherryPy服务器。
我正在按照本教程在服务器端显示PHP代码。
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教程中描述的内容翻译成如下形式:
upload.php
def upload(self): [...]
当服务器收到请求时,我可以看到cherrypy.request.headers['Content-Length'] == 5676 这就是我要上传的文件的长度,因此我假设整个文件已发送到服务器。
cherrypy.request.headers['Content-Length'] == 5676
如何获取文件的内容?
至少看起来像下面这样。在Firefox和Chromium中进行了测试。如果您需要支持旧版浏览器,我会看一些JavaScript库来实现polyfills和fallback。
#!/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)