2012-09-02 2 views
2

코드 양식 here을 사용하여 Python CGI 스크립트를 통해 단일 양식 필드를 사용하여 여러 파일을 업로드하고 싶습니다. 최신 브라우저는 herehere에 대해이 기능을 지원하는 것으로 보입니다. HTML 양식은 간단 보인다 내가 처음에 가정Python CGI를 통해 단일 양식 필드를 통해 여러 파일 업로드

file=file0&file=file1

이 될 것입니다 :

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

file0file1은 다음 HTML5 input multiple attribute 당이 발생합니다 이름을 두 개의 파일을 선택하려면이 양식을 사용하여 정렬 배열하지만 분리에 대한 앰퍼샌드를 사용하는 것 같습니다.

코드를 수정하고 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 

두 파일 선택 오류 : .filename 참조가 제거되면, 세 번째 오류가 생성됩니다

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 

, 하나 또는 두 개의 파일을 동일 선택됨 :

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 라이브러리가 여러 파일 업로드를 지원하는지는 잘 모르겠지만 오류는 간단합니다. file[]이라는 필드를 HTML에서 호출했지만 Python에서는 단순히 file을 참조합니다. 그들은 동일하지 않습니다. 나는 단순히 PHP-ism을 삭제하고 필드를 단지 file이라고 부를 것을 권한다.

+0

의견에 감사드립니다. PHP-ism이 제거되었으며 문제의 오류가 업데이트되었습니다. – Astron

관련 문제