2017-06-28 56 views
6

staram się powtarzać następującą prośbę curl:Jak przesłać plik jako element tablicy z plakatem?

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 

z poster użycia:

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) 

Ale wygląda image pole jest przekazywana jako pojedynczego pola, gdy tablica powinna być przyjęta. Użycie nazwy image[0] jako nazwy nie pomaga.

Jak mogę to naprawić?

+0

Czy zmiana zmiennej 'name' w' mp_parms.append (MultipartParam (name, 'to' 'image [0] 'etc naprawi? To jest faktycznie fieid, który tworzy wieloczęściową nazwę pola formularza – drew010

+0

@ drew010 I' ve powiedział w pytaniu, które próbowałem.Czy wygląda jak wsporniki zmiany plakatu na% xxx. –

+0

co '' '' '' i '[]' nie jest w znaku escape.so nie sądzę, że to jest powód – obgnaw

Odpowiedz

5

Przełączyłem przykład, aby użyć żądań, ponieważ nie mam zainstalowanego pakietu SDK aplikacji Google, ale działa poniższy kod.

Jedną z ważnych zmian była zmiana image na image[], aby zdalny koniec rozpoznał wiele wejść o tej samej nazwie. Nie jestem pewien, czy to samo dotyczyłoby urlfetch, ale musiałem dodać dodatkową \r\n po treści surowego postu.

Dla ilustracji i testów, kazałem to załadować drugi obraz.

pierwsze, kod:

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 

Skrypt test.php IT postów do zawiera i pokazuje wyjście jak:

// 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" 

Produkowany następujące stanowiska chwycił w Wireshark:

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 

Mam nadzieję, że to pomaga. Nie jestem pewien, czy API będzie się tym przejmować, ale możesz chcieć kodować dane obrazu w base64 i ustawić kodowanie treści na base64, aby zachować surowy plik binarny poza postem.

Jeśli nadal tkwisz po zintegrowaniu niektórych zmian, daj mi znać!

+0

Dzięki. 'requests' wymaga ręcznej instalacji wielu zależności, GAE wymaga starej wersji 2.3.0 (w przeciwnym razie nie działa z całkowitą wartością długości treści iz wbudowaną biblioteką SSL), ale udało mi się to naprawić i próbowałem przetestować kod z 'request'. Ale wynik jest taki sam jak w przypadku 'urlfetch'. Wygląda na to, że problem dotyczy nazwy pola. 'image []' jest zakodowany na 'image% 5B% 5D' i wygląda na to, że serwer zewnętrzny nie jest w stanie go rozpoznać (kiedy robi to twój serwer PHP). –

+0

To dziwne, że napotkasz kodowanie na nazwie pola, gdzie moje nieprzetworzone przechwycenie w wireshark pokazuje to jako literalne 'image []'. Czy jesteś w stanie wykonać przechwytywanie lub czy API jest przez HTTPS? – drew010

+0

Dzięki za pomoc. Problem polegał na używaniu starej wersji modułu plakatowego;). –