至少看起来像下面这样。在Firefox和Chromium中进行了测试。如果您需要支持旧版浏览器,我会看一些Javascript库来实现polyfills和fallback。
#!/usr/bin/env python# -*- coding: utf-8 -*-import osimport shutilimport cherrypyconfig = { '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)


