php - 使用 httplib 和 python 将字符串和缓冲区发送到服务器

标签 php python httplib

如何在 python Web 服务中使用 httplib 将带有文件对象的参数 POST 到 URL。

我使用以下脚本:

import httplib
import urllib
params = urllib.urlencode({"@str1":"string1", "@str2":"string2", "@file":"/local/path/to/file/in/client/machine", "@action":"action.php" })
headers = {"Content-type":"application/pdf , text/*" }
conn = httplib.HTTPConnection("192.168.2.17")
conn.request("POST", "/SomeName/action.php", params, headers)
response = conn.getresponse()
print response.status, response.reason
data = response.read()
data
conn.close()

我有以下输出:

200
OK
<html>.....some html code </html>

我编写了一些 php 代码来将这些字符串和文件保存在数据库中 我的问题是,我只获取文件路径作为字符串,而不是我的文件。 可能我必须发送文件对象,例如,

file_obj = open("filename.txt","r")
conn.request("POST", "/SomeName/action.php", file_obj, headers)

但我想发送字符串和文件。有什么建议来解决这个问题吗?

编辑 我将我的代码更改如下: 当我直接使用 httplib 发送 pdf 文件到我的服务器时,该文件保存为 BIN 文件。

def document_management_service(self,str_loc_file_path,*args):
    locfile = open(str_loc_file_path,'rb').read()
    host = "some.hostname.com"
    selector = "/api/?task=create"
    fields = [('docName','INVOICE'),('docNumber','DOC/3'),('cusName','name'),('cusNumber','C124'),('category','INVOICE'),('data','TIJO MRS,SOME/DATA/CONTENT,Blahblah,2584.00,blahblah'),('action','create')]
    files = [('strfile','File.pdf',locfile)]
    response = self.post_multipart(host, selector, fields, files)
    print response
    pass

def post_multipart(self,host, selector, fields, files):
    content_type, body = self.encode_multipart_formdata(fields, files)
    h = httplib.HTTP(host)
    h.set_debuglevel(1)
    h.putrequest('POST', selector)
    h.putheader('content-type', content_type)
    h.putheader('content-length', str(len(body)))
    h.putheader('Host', host)
    h.endheaders()
    h.send(body)
    errcode, errmsg, headers= h.getreply()
    return h.file.read()

def encode_multipart_formdata(self, fields, files):
    LIMIT = '----------lImIt_of_THE_fIle_eW_$'
    CRLF = '\r\n'
    L = []
    for (key, value) in fields:
        L.append('--' + LIMIT)
        L.append('Content-Disposition: form-data; name="%s"' % key)
        L.append('')
        L.append(value)
    for (key, filename, value) in files:
        L.append('--' + LIMIT)
        L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
        L.append('Content-Type: %s' % self.get_content_type(filename))
        L.append('')
        L.append(value)
    L.append('--' + LIMIT + '--')
    L.append('')
    body = CRLF.join(L)
    content_type = 'multipart/form-data; boundary=%s' % LIMIT
    return content_type, body

def get_content_type(self, filename):
    return mimetypes.guess_type(filename)[0] or 'application/octet-stream'

我已调试请求,显示为:

[('content-length', '4191'), ('accept-ranges', 'bytes'), ('server', 'Apache/2.2.12 (Ubuntu)'), ('last-modified', 'Tue, 23 Oct 2012 04:46:36 GMT'), ('etag', 'W/"567dd-105f-4ccb2a7a9a500"'), ('date', 'Tue, 23 Oct 2012 04:46:36 GMT'), ('content-type', 'application/pdf')]
multipart/form-data; boundary=----------lImIt_of_THE_fIle_eW_$

我没有尝试请求,因为我想用httplib(没有任何外部库)解决这个问题

最佳答案

要在正文中发布参数和文件,您可以使用multipart/form-data内容类型:

#!/usr/bin/env python
import requests # $ pip install requests

file = 'file content as a file object or string'
r = requests.post('http://example.com/SomeName/action.php',
                  files={'file': ('filename.txt', file)},
                  data={'str1': 'string1', 'str2': 'string2'})
print(r.text) # response

requests.post 向服务器发送如下内容:

POST /SomeName/action.php HTTP/1.1
Host: example.com
Content-Length: 449
Content-Type: multipart/form-data; boundary=f27f8ef67cac403aaaf433f83742bd64
Accept-Encoding: identity, deflate, compress, gzip
Accept: */*

--f27f8ef67cac403aaaf433f83742bd64
Content-Disposition: form-data; name="str2"
Content-Type: text/plain

string2
--f27f8ef67cac403aaaf433f83742bd64
Content-Disposition: form-data; name="str1"
Content-Type: text/plain

string1
--f27f8ef67cac403aaaf433f83742bd64
Content-Disposition: form-data; name="file"; filename="filename.txt"
Content-Type: text/plain

file content as a file object or string
--f27f8ef67cac403aaaf433f83742bd64--

要使用 httplib 重现它,请参阅 POST form-data with Python example .

如果您的参数不包含太多数据,一个更简单的解决方案是将它们传递到 url 查询部分,并让正文仅包含文件:

#!/usr/bin/env python
import urllib
import requests # $ pip install requests

params = {'str1': 'string1', 'str2': 'string2', 'filename': 'filename.txt'}
file = 'file content as a file object or string, etc'    
url = 'http://example.com/SomeName/action.php?' + urllib.urlencode(params)
r = requests.post(url, data=file, headers={'Content-Type': 'text/plain'})
print(r.text) # response

它对应于以下HTTP请求:

POST /SomeName/action.php?str2=string2&str1=string1&filename=filename.txt HTTP/1.1
Host: example.com
Content-Length: 39
Content-Type: text/plain
Accept-Encoding: identity, deflate, compress, gzip
Accept: */*

file content as a file object or string

如果需要的话,转换为 httplib 应该会更容易。

关于php - 使用 httplib 和 python 将字符串和缓冲区发送到服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12895981/

相关文章:

php - 如何在php循环中显示隐藏的数据类型?

python - 我正在尝试使用 cv2.solvePnP() 但出现错误

python - Tornado 如何在任意位置提供单个静态文件?

python - 在 Ubuntu 上的 Python 3 中使用 Pip 并导入包

Python httplib.HTTPSConnection 超时——连接与响应

php - 每次加载页面时更改元素的位置

php - 如何获取 mysql 查询并将其存储在 var 中

javascript - onBlur触发的多个表单字段如何使用JS fetch api系统替换jQuery AJAX系统?

python - 发送 httplib 的多个请求,引发回溯异常

python - 尝试 POST 时出现 "getaddr info failed"错误