2014-11-11 3 views
0

Я пытаюсь загрузить сразу несколько файлов на свой сервер CherryPy.Загрузка файла в ajax в CherryPy

Я следую this tutorial, который показывает код 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, описанный в учебнике в нечто вроде этого:

def upload(self): 
    [...] 

Когда сервер получает запрос, я могу видеть, что cherrypy.request.headers['Content-Length'] == 5676 который длина файла, который я пытаюсь загрузить, поэтому я предполагаю, что весь файл был отправлен на сервер.

Как я могу получить содержимое файла?

+0

См [cherrypy._cprequest.Request.body] (https://cherrypy.readthedocs.org/en/3.3.0/refman/_cprequest.html#cherrypy._cprequest.Request.body). Кажется, вам нужно указать тип содержимого на стороне JS, чтобы предотвратить синтаксический анализ формы, а затем обработать «тело». – jwalker

ответ

1

По меньшей мере это выглядит следующим образом. Протестировано в Firefox и Chromium. Если вам нужно поддерживать устаревшие браузеры, я бы посмотрел на библиотеку JavaScript для полиполнений и резервного копирования.

#!/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) 
Смежные вопросы