# 1 HTTP 中 post 请求的常用三种方式
- application/x-www-form-urlencoded (URL encoded)
- multipart/form-data (键值对型数据)
- application/json (Json 类型数据)
- text/xml (xml)
# 1.1 application/x-www-form-urlencoded
如果不设置 Content-type 的值,默认就是 urlencoded。
form表单默认的数据格式,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。
# python脚本
import requests
url = "http://httpbin.org/post"
data = {"name":"西园公子","age":"666"}
headers = {"Content-type":"application/x-www-form-urlencoded"}
content = requests.post(url=url,data=data,).text
print(content)
# 网络请求:
POST http://httpbin.org/post HTTP/1.1
Host httpbin.org
User-Agent python-requests/2.24.0
Accept-Encoding gzip, deflate
Accept */*
Content-Length 49
Content-Type application/x-www-form-urlencoded
Connection keep-alive
# 下面是表单内容
# name=%E8%A5%BF%E5%9B%AD%E5%85%AC%E5%AD%90&age=666 可以看出汉字是使用utf8编码的
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 1.2 multipart/form-data
这种编码方式,通常是用在客户端向服务端传送大文件数据,如:图片或者文件。
这种格式的数据会有一个边界线 boundary (如 ———WebKitFormBoundaryBRi81vNtMyBL97Rb),表明下面的都是表单内容,然后紧接着跟的是表单中 的第一个键值对中的名称,而后一个换行,跟着值。然后再生成一个boundary 字符串分界线,用于分割不同的键值。
消息主体以boundary开始,紧接着就是内容描述信息,然后是回车,最后是字段具体的 内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体以boundary结束。
# python脚本
import requests
from requests_toolbelt import MultipartEncoder
m = MultipartEncoder(
fields={'field0': 'value1', 'field1': 'value2', 'field2': ('filename', open('data.txt', 'rb'), 'text/plain')}
)
content = requests.post('http://httpbin.org/post', data=m,
headers={'Content-Type': m.content_type}).text
print(content)
print(m.content_type)
# 1、网络请求:
POST http://httpbin.org/post HTTP/1.1
Host: httpbin.org
User-Agent: python-requests/2.24.0
Accept-Encoding: gzip, deflate
Accept: */*
Content-Type: multipart/form-data; boundary=e48c73a7a42e403d868095dc3d060962
Content-Length: 222
Connection: keep-alive
# 下面是编码的表单内容
# --e48c73a7a42e403d868095dc3d060962
# Content-Disposition: form-data; name="field0"
#
# value1
# --e48c73a7a42e403d868095dc3d060962
# Content-Disposition: form-data; name="field1"
#
# value2
# --e48c73a7a42e403d868095dc3d060962--
# Content-Disposition: form-data; name="field2"; filename="filename"
# Content-Type: text/plain
#
# ä½ å¥½ï¼è¥¿åå
¬åï½
# --25c88ddc918d40e7a3cd5be0d62476b7--
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 1.3 application/json
用来告诉服务端消息主体是序列化后的 JSON 字符串。
import requests
import json
url="http://httpbin.org/post"
p_data = {"name": "公子哥", "hobby": "coding"}
content = requests.post(url, json=json.dumps(p_data),
headers={'Content-Type': "application/json"}).text
print(content)
# 1、原生网络请求
POST /post HTTP/1.1
Host: httpbin.org
User-Agent: python-requests/2.24.0
Accept-Encoding: gzip, deflate
Accept: */*
Content-Type: application/json
Content-Length: 62
Connection: keep-alive
# 下面是编码成json数据 的表单内容
"{\"name\": \"\\u516c\\u5b50\\u54e5\", \"hobby\": \"coding\"}"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 主线程退出对子线程的影响
对于程序来说,如果主进程在子进程还未结束时就已经退出,那么Linux内核会将子进程的父进程ID改为1(也就是init进程),当子进程结束后会由init进程来回收该子进程。
主线程退出后子线程的状态依赖于它所在的进程,如果进程没有退出的话子线程依然正常运转。如果进程退出了,那么它所有的线程都会退出,所以子线程也就退出了。
主线程中的main函数执行完ruturn后弹栈,然后调用glibc库函数exit,exit进行相关清理工作后调用_exit系统调用退出该进程。所以,这种情况实际上是因为进程运行完毕退出导致所有的线程也都跟着退出了,并非是因为主线程的退出导致子线程也退出。
# 线程对象与线程函数
线程对象可能先于线程函数结束,应该保证线程对象的生命周期在线程函数执行完时仍然存在,可以join 阻塞线程等待线程函数执行完或者通过 detach 方式让线程在后台执行,或者是将线程对象保存到容器中,保证线程对象的生命周期。
detach 将线程对象和线程分离,但是需要注意的是,deteach 后的线程。
# CMake 为什么无法正确生成 Compile_command.json?
CMake(自 2.8.5 起)支持使用选项 CMAKE_EXPORT_COMPILE_COMMANDS
为 Unix Makefile 构建(Ninja 构建中)生成编译数据库。所以生成编译数据库需要 Ninja 的支持。