如何用海报上传文件作为数组元素?
How to upload file as array element with poster?
我正在尝试重复以下 curl 请求:
curl -i -k -H "Content-Type: multipart/form-data" \
-F "method=uploadphoto" \
-F "version=1.2.3" \
-F "format=json" \
-F "image[0]=@/Users/user/Downloads/file.jpeg" \
https://example.com/api
poster 用法:
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)
但看起来 image
字段作为单个字段传递,而数组应该传递。使用 image[0]
作为名称没有帮助。
我该如何解决?
我将示例切换为使用请求,因为我没有安装 Google App SDK,但下面的代码有效。
一个重要的变化是将 image
更改为 image[]
,以便远程端可以识别具有相同名称的多个输入。不确定是否同样适用于 urlfetch 但我不得不在原始 post 正文之后添加一个额外的 \r\n
。
为了说明和测试,我让它上传了第二张图片。
一、代码:
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
test.php
脚本 post 包含 <?php var_dump($_POST, $_FILES, $_SERVER);
并显示如下输出:
// 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"
它在 Wireshark 中生成了以下 POST:
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
希望对您有所帮助。我不确定 API 是否会关心,但您可能希望对图像数据进行 base64 编码并将内容编码设置为 base64
以将原始二进制文件排除在 post 之外。
如果您在集成一些更改后仍然遇到困难,请告诉我!
我正在尝试重复以下 curl 请求:
curl -i -k -H "Content-Type: multipart/form-data" \
-F "method=uploadphoto" \
-F "version=1.2.3" \
-F "format=json" \
-F "image[0]=@/Users/user/Downloads/file.jpeg" \
https://example.com/api
poster 用法:
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)
但看起来 image
字段作为单个字段传递,而数组应该传递。使用 image[0]
作为名称没有帮助。
我该如何解决?
我将示例切换为使用请求,因为我没有安装 Google App SDK,但下面的代码有效。
一个重要的变化是将 image
更改为 image[]
,以便远程端可以识别具有相同名称的多个输入。不确定是否同样适用于 urlfetch 但我不得不在原始 post 正文之后添加一个额外的 \r\n
。
为了说明和测试,我让它上传了第二张图片。
一、代码:
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
test.php
脚本 post 包含 <?php var_dump($_POST, $_FILES, $_SERVER);
并显示如下输出:
// 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"
它在 Wireshark 中生成了以下 POST:
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
希望对您有所帮助。我不确定 API 是否会关心,但您可能希望对图像数据进行 base64 编码并将内容编码设置为 base64
以将原始二进制文件排除在 post 之外。
如果您在集成一些更改后仍然遇到困难,请告诉我!