3

こちらのコードを使用して、PythonCGIスクリプトを介して単一のフォームフィールドを使用して複数のファイルをアップロードしたいと思います。新しいブラウザは、ここここでこの機能をサポートしているようです。HTMLフォームは単純なようです。

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

このフォームを使用して2つのファイル名を選択するfile0と、 HTML5file1ごとに次の複数の属性が入力されます。

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

2つのファイルが選択されたエラー:

 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参照が削除されると、3番目のエラーが生成されます。これは、選択されている1つまたは2つのファイルの場合と同じです。

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
4

2 に答える 2

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)
于 2012-09-03T00:28:14.260 に答える
0

cgiライブラリが複数のファイルのアップロードをサポートしているかどうかはわかりませんが、エラーは単純ですfile[]。HTMLでフィールドを呼び出しましたが、Pythonでは単にを参照していますfile。それらは同じではありません。PHP-ismを削除し、フィールドを呼び出すことをお勧めしますfile

于 2012-09-02T22:32:41.483 に答える