2012-09-02 36 views
2

我想通过使用代码here的Python CGI脚本使用单个表单域上传多个文件。较新的浏览器似乎支持此功能,每herehere。 HTML表单看起来非常简单:通过Python通过单个表单域上传多个文件CGI

<input name="file" type="file" multiple="" />

使用此表来选择两个文件名file0file1将导致以下每HTML5 input multiple attribute

file=file0&file=file1

我最初认为这将是一个排序数组,但它似乎使用&符号分隔。

我尝试修改代码并使用以下代码添加for语句以遍历表单字段中指定的每个文件,但未成功(请参阅下面的错误)。如果使用for语句不是最佳路线,那么我也可以使用其他可能使用Python的想法。

#!/usr/bin/python 
import cgi, os 

form = cgi.FieldStorage() 

# Generator to buffer file chunks 
def fbuffer(f, chunk_size=10000): 
    while True: 
     chunk = f.read(chunk_size) 
     if not chunk: break 
     yield chunk 

for fileitem in form['file']: 

    # A nested FieldStorage instance holds the file 
    fileitem = form['file'] 

    # Test if the file was uploaded 
    if fileitem.filename: 

     # strip leading path from file name to avoid directory traversal attacks 
     fn = os.path.basename(fileitem.filename) 
     f = open('/var/www/domain.com/files' + fn, 'wb', 10000) 

     # Read the file in chunks 
     for chunk in fbuffer(fileitem.file): 
     f.write(chunk) 
     f.close() 
     message = 'The file "' + fn + '" was uploaded successfully' 

    else: 
     message = 'No file was uploaded' 

    print """\ 
    Content-Type: text/html\n 
    <html><body> 
    <p>%s</p> 
    </body></html> 
    """ % (message,) 

单个文件选择的误差:

Traceback (most recent call last):, referer: https://www.domain.com/files/upload.htm 
    File "/usr/lib/cgi-bin/test.py", line 13, in <module>, referer: https://www.domain.com/files/upload.htm 
    for fileitem in form['file']:, referer: https://www.domain.com/files/upload.htm 
    File "/usr/lib/python2.6/cgi.py", line 518, in __iter__, referer: https://www.domain.com/files/upload.htm 
    return iter(self.keys()), referer: https://www.domain.com/files/upload.htm 
    File "/usr/lib/python2.6/cgi.py", line 583, in keys, referer: https://www.domain.com/files/upload.htm 
    raise TypeError, "not indexable", referer: https://www.domain.com/files/upload.htm 
TypeError: not indexable, referer: https://www.domain.com/files/upload.htm 
Premature end of script headers: test.py, referer: https://www.domain.com/files/upload.htm 

两个文件选择的误差:

Traceback (most recent call last):, referer: https://www.domain.com/files/upload.htm 
    File "/usr/lib/cgi-bin/test.py", line 19, in <module>, referer: https://www.domain.com/files/upload.htm 
    if fileitem.filename:, referer: https://www.domain.com/files/upload.htm 
AttributeError: 'list' object has no attribute 'filename', referer: https://www.domain.com/files/upload.htm 
Premature end of script headers: test.py, referer: https://www.domain.com/files/upload.htm 

如果.filename引用都被删除时,产生第三误差,相同的单个或两个文件被选中:

Traceback (most recent call last):, referer: https://www.domain.com/files/upload.htm 
    File "/usr/lib/cgi-bin/test.py", line 24, in <module>, referer: https://www.domain.com/files/upload.htm 
    fn = os.path.basename(fileitem), referer: https://www.domain.com/files/upload.htm 
    File "/usr/lib/python2.6/posixpath.py", line 111, in basename, referer: https://www.domain.com/files/upload.htm 
    i = p.rfind('/') + 1, referer: https://www.domain.com/files/upload.htm 
AttributeError: 'list' object has no attribute 'rfind', referer: https://www.domain.com/files/upload.htm 
Premature end of script headers: test.py, referer: https://www.domain.com/files/upload.htm 

回答

2

删除for file in form。该错误意味着form['file']是一个列表。

添加到html表格:method=post enctype=multipart/form-data

import shutil 

if 'file' in form: 
    filefield = form['file'] 
    if not isinstance(filefield, list): 
     filefield = [filefield] 

    for fileitem in filefield: 
     if fileitem.filename: 
      fn = secure_filename(fileitem.filename) 
      # save file 
      with open('/var/www/domain.com/files/' + fn, 'wb') as f: 
       shutil.copyfileobj(fileitem.file, f) 
+0

更新了'for'语句和新的相应错误。建议我也更改保存方法?如果是这样,我应该删除for语句下的所有现有代码吗?谢谢 – Astron

+0

@Astron:我已经更新了答案。 – jfs

0

我不知道cgi库是否支持上传多个文件,但是你的错误很简单:你已经在HTML中调用了你的字段file[],但是在Python中你只需要指向file。他们不一样。我建议简单地删除PHP主题并调用该字段只需file

+0

感谢您的反馈。 PHP-ism被删除并更新了有问题的错误。 – Astron

相关问题