做阿里巴巴网站口碑/链接
- 提问
在过往的使用中对于post请求总是无差别的requests.post(url='', data=json.dumps(data))
, 这是错误的使用方式!!!
那么这个data到底如果给值呢?
- 直接给出结论
data是dict时:
requests 内部对这个dict进行了key-value+&
的字符串拼接. 即data作为表单方式进行的提交,对应的requestContent-Type
请求头为application/x-www-form-urlencoded
data是json.dumps()
序列化后的json字符串
时,原样传输, 且报文不携带Content-Type
请求头, 此时在服务器接受到的报文当然也是可以反序列化json对象出来, 但是没有Content-Type: application/json
请求头,如果需要这个请求头不要走弯路直接requests.post(url, json=data)
这里传dict.
- 直接通过
wireshark
抓包即可以看到区别, 以 dict类型的data为例:-
requests.post(url='', data=data)
-
requests.post(url='', data=json.dumps(data))
-
requests.post(url='', json=data)
-
下面给出一个TcpServer来演示下,刚好也复习下TcpServer.py的定义方式
-
Tcpserver.py:
import socket# 创建 socket 对象 import time, threadingsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # bind 服务 sock.bind(('127.0.0.1', 8081))# 开启服务端socket监听 sock.listen(1) # 设置 100 个 连接上限sock.setblocking(False)readalbe_list = [] # 可读队列 writeable_list = [] # 可写队列del_list = []def read():print('read running')while 1:for client_socket in readalbe_list:# time.sleep(5)recv_flag = 0# print(f'客户端连接{client_socket}')try:response = b""chunk = client_socket.recv(1)while chunk:recv_flag = 1response += chunkchunk = client_socket.recv(10)print(f'line32: chunk--:: {chunk}')except BlockingIOError as err:if recv_flag:writeable_list.append(client_socket)print(123)if response:print('response: {}'.format(response))threading.Thread(target=read).start()while 1:try:client_socket, client_addr = sock.accept() # 接收客户端 connect 返回 客户端 socket和 客户端的 地址print(f"接收到新 连接加入可写队列, 客户端socket: {client_socket} \n 客户端地址: {client_addr}")time.sleep(1)readalbe_list.append(client_socket)except BlockingIOError as err:passfor client_socket in writeable_list:send_flag = 0try:send_flag = 1client_socket.send(f'welcome {client_socket}'.encode())except OSError as err:if send_flag:del_list.append(client_socket)if client_socket in readalbe_list:readalbe_list.remove(client_socket) # 短连接 收发完成移除队列client_socket.close()for each in del_list:if each in writeable_list:writeable_list.remove(each)del_list.clear()
-
client_demo.py
import requestsdata = {"id": 99800005,"hot_push_program": [{"program_id": 200370447,"program_name": "乐享汇: 新的唱响 演唱会(11)","content_type": 1999,"starttime": time.time(),"endtime": time.time()}],"accesstoken": "TOKEN3590","relevance_id": 0 } requests.post(url="http://127.0.0.1:8081/", data=data)
-
Tcpserver.py的打印:
POST / HTTP/1.1 Host: 127.0.0.1:8081 Connection: keep-alive Accept-Encoding: gzip, deflate Accept: */* User-Agent: python-requests/2.22.0 Content-Length: 188 Content-Type: application/x-www-form-urlencodedhot_push_program=program_name&hot_push_program=starttime&hot_push_program=endtime&hot_push_program=content_type&hot_push_program=program_id&id=99800005&accesstoken=TOKEN3590&relevance_id=0
- 附: 另外表单还有另外一种
Content-Type
即multipart/form-data; boundary=xxx
这种方式是以bondary
为分割符分割报文流,适用于海报、大文件等文件流
传输
下附两种表单请求头的区别 multipart/form-data
以上传海报的案例:
可以看到multipart/form-data
格式的数据在tcp报文呈现出的会是指定一个分隔符boundary
,x-www-form-urlencoded
报文段也是有分隔符不过是默认的&