2017-06-28 1 views
6

Ich versuche, die folgende curl Anfrage zu wiederholen:Wie lade ich eine Datei als Array-Element mit Poster hoch?

curl -i -k -H "Content-Type: multipart/form-data" \ 
    -F "method=uploadphoto" \ 
    -F "version=1.2.3" \ 
    -F "format=json" \ 
    -F "image[0][email protected]/Users/user/Downloads/file.jpeg" \ 
    https://example.com/api 

mit poster Nutzung:

from poster.encode import multipart_encode, MultipartParam 

file_content = open('/Users/user/Downloads/file.jpeg', 'rb') 
url = 'https://example.com/api' 
headers = { 
    'Content-Type': 'multipart/form-data' 
} 
parms = { 
    'method': 'uploadphoto', 
    'version': '1.2.3', 
    'format': 'json' 
} 
mp_parms = [] 
for name, value in parms.items(): 
    mp_parms.append(MultipartParam(name, value, filetype='text/plain')) 
file_photo = MultipartParam('image', file_content, 'file.jpeg', 'application/image') 
mp_parms.append(file_photo) 
parameters, headers = multipart_encode(mp_parms) 
response = urlfetch.Fetch(url, payload=''.join(parameters), headers=headers, method=urlfetch.POST, deadline=60) 

Aber sieht aus wie image Feld als einzelnes Feld geführt wird, wenn Array übergeben werden sollte. Die Verwendung von image[0] als Name hilft nicht.

Wie kann ich es beheben?

+0

Ändert die Variable 'name' in' mp_parms.append (MultipartParam (name, '' 'image [0]' etc) es? Das ist tatsächlich die Fieid, die den mehrteiligen Formularfeldnamen erstellt. – drew010

+0

@ drew010 I ' Ich habe in der Frage gesagt, dass ich es ausprobiert habe. Sieht so aus, als ob Poster Klammern an% xxx ändert. –

+0

was ist das 'lurfetch'is? und' [] 'nicht im Escape-Zeichen.so glaube ich nicht, dass es der Grund ist. – obgnaw

Antwort

5

Ich habe das Beispiel für die Verwendung von Anfragen geändert, da ich das Google App SDK nicht installiert habe, aber der folgende Code funktioniert.

Eine wichtige Änderung war die Änderung image zu image[] zu machen, damit das entfernte Ende mehrere Eingänge mit dem gleichen Namen erkennen würde. Nicht sicher, ob das selbe mit urlfetch gelten würde, aber ich musste einen zusätzlichen \r\n nach dem rohen Postkörper hinzufügen.

Für Illustration und Tests, ich hatte es ein zweites Bild hochladen.

Zuerst wird der Code:

from poster.encode import multipart_encode, MultipartParam 
import requests 
from pprint import pprint 

file_content = open('/home/me/Pictures/admin.jpg', 'rb').read() 
file_content2 = open('/home/me/Pictures/ed.jpeg', 'rb').read() 
url = 'http://localhost/test.php' 
parms = { 
    'method': 'uploadphoto', 
    'version': '1.2.3', 
    'format': 'json' 
} 
mp_parms = [] 
for name, value in parms.items(): 
    mp_parms.append(MultipartParam(name, value, filetype='text/plain')) 

file_photo = MultipartParam('image[]', file_content, 'file.jpeg', 'image/jpg') 
mp_parms.append(file_photo) 

file_photo = MultipartParam('image[]', file_content2, 'test.jpeg', 'image/jpg') 
mp_parms.append(file_photo) 

parameters, headers = multipart_encode(mp_parms) 

pprint(headers) 

#response = urlfetch.Fetch(url, payload=''.join(parameters), headers=headers, method=urlfetch.POST, deadline=60) 

r = requests.post(url, data=''.join(parameters) + "\r\n", headers=headers) 

print r.text 

Das test.php Skript es Beiträge enthält und zeigt eine Ausgabe wie:

// The post data: 
array(3) { 
    ["version"]=> 
    string(5) "1.2.3" 
    ["method"]=> 
    string(11) "uploadphoto" 
    ["format"]=> 
    string(4) "json" 
} 

// The uploaded files (both of them as expected): 
array(1) { 
    ["image"]=> 
    array(5) { 
    ["name"]=> 
    array(2) { 
     [0]=> 
     string(9) "file.jpeg" 
     [1]=> 
     string(9) "test.jpeg" 
    } 
    ["type"]=> 
    array(2) { 
     [0]=> 
     string(9) "image/jpg" 
     [1]=> 
     string(9) "image/jpg" 
    } 
    ["tmp_name"]=> 
    array(2) { 
     [0]=> 
     string(14) "/tmp/phpnbpGGx" 
     [1]=> 
     string(14) "/tmp/php7TVcyL" 
    } 
    ["error"]=> 
    array(2) { 
     [0]=> 
     int(0) 
     [1]=> 
     int(0) 
    } 
    ["size"]=> 
    array(2) { 
     [0]=> 
     int(71066) 
     [1]=> 
     int(30450) 
    } 
    } 
} 

# some server vars: 
["CONTENT_LENGTH"]=> 
    string(6) "102186" 
["CONTENT_TYPE"]=> 
    string(62) "multipart/form-data; boundary=73772149e2ef4a5daf9b5eb18a5d73f5" 

Es wird folgendes POST wie in Wireshark packte:

POST /test.php HTTP/1.1 
Host: localhost 
Connection: keep-alive 
Accept-Encoding: gzip, deflate 
Accept: */* 
User-Agent: python-requests/2.12.1 
Content-Length: 102186 
Content-Type: multipart/form-data; boundary=176473ffab3146b5bfffc6185ad9474a 

--176473ffab3146b5bfffc6185ad9474a 
Content-Disposition: form-data; name="version" 
Content-Type: text/plain 

1.2.3 
--176473ffab3146b5bfffc6185ad9474a 
Content-Disposition: form-data; name="method" 
Content-Type: text/plain 

uploadphoto 
--176473ffab3146b5bfffc6185ad9474a 
Content-Disposition: form-data; name="format" 
Content-Type: text/plain 

json 
--176473ffab3146b5bfffc6185ad9474a 
Content-Disposition: form-data; name="image[]"; filename="file.jpeg" 
Content-Type: image/jpg 

......JFIF.....H.H.....C................................... 
...snip... 
..K5{......1....fh........k..n... 
--176473ffab3146b5bfffc6185ad9474a 
Content-Disposition: form-data; name="image[]"; filename="test.jpeg" 
Content-Type: image/jpg 

......JFIF.............;CREATOR: gd-jpeg v1.0 (using IJG JPEG v80), quality = 90 
...snip... 
6.......~.h.j......}29..b~.h.).2.!E..tU.........L....d...lv..+....f)Y... 
--176473ffab3146b5bfffc6185ad9474a-- 

HTTP/1.1 200 OK 

Ich hoffe, dass hilft. Ich bin mir nicht sicher, ob die API das interessiert, aber Sie könnten Base64 die Bilddaten kodieren und das Content-Encoding auf base64 setzen, um die rohe Binärdatei aus dem Post herauszuhalten.

Wenn Sie immer noch stecken nach der Integration einige der Änderungen lassen Sie es mich wissen!

+0

Danke. 'Anfragen' erfordert manuelle Installation von vielen Abhängigkeiten, GAE erfordert alte Version 2.3.0 (sonst funktioniert es nicht mit Integer-Wert des Inhalts Länge und mit integrierten SSL-Bibliothek), aber ich habe es zu beheben und versuchte, meine zu testen Code mit 'Anfragen'. Das Ergebnis ist jedoch dasselbe wie bei "Urlchetch". Es sieht aus wie das Problem mit dem Feldnamen ist. 'image []' ist in 'image% 5B% 5D' kodiert und sieht so aus, als ob der Server eines Drittanbieters diesen nicht erkennen kann (wenn Ihr PHP-Server dies tut). –

+0

Das ist komisch, dass Sie auf den Namen des Felds stoßen, wo meine rohe Rohdatenaufnahme von wireshark es als das Literal 'image []' zeigt. Können Sie eine Erfassung durchführen oder ist die API über https? – drew010

+0

Danke für Ihre Hilfe. Das Problem wurde mit alter Version des Postermoduls verwendet;). –

Verwandte Themen