Content-Type 实体头部用于指示资源的MIME类型 media type 。
在响应中,Content-Type标头告诉客户端实际返回的内容的内容类型。浏览器会在某些情况下进行MIME查找,并不一定遵循此标题的值; 为了防止这种行为,可以将标题 X-Content-Type-Options 设置为 nosniff。

application/x-www-form-urlencoded

php服务端代码:

<?php
echo(file_get_contents('php://input') . "\r\n");
var_dump($_POST);
# var_dump($_FILES);
print('REQUEST_METHOD:' . $_SERVER['REQUEST_METHOD'] . "\r\n");
print('CONTENT_TYPE:' . $_SERVER['CONTENT_TYPE']);

python客户端代码:

import requests

res = requests.post(url='http://test/content_type.php',
                    data={'username': 'xiaoming', 'password': '123'},
                    headers={'Content-Type': 'application/x-www-form-urlencoded'}
                    )
# print(res.request.body)
print(res.text)
# print(res.request.headers)

结果:

multipart/form-data

multipart/form-data 可用于HTML表单从浏览器发送信息给服务器。作为多部分文档格式,它由边界线(一个由’–'开始的字符串)划分出的不同部分组成。每一部分有自己的实体,以及自己的 HTTP 请求头,Content-Disposition和 Content-Type 用于文件上传领域,最常用的 (Content-Length 因为边界线作为分隔符而被忽略)。

php服务端:

<?php
echo(file_get_contents('php://input') . "\r\n");
var_dump($_POST);
var_dump($_FILES);
print('REQUEST_METHOD:' . $_SERVER['REQUEST_METHOD'] . "\r\n");
print('CONTENT_TYPE:' . $_SERVER['CONTENT_TYPE']);

python客户端:

import requests

res = requests.post(url='http://test/content_type.php',
                    data={'username': 'xiaoming', 'password': '123'},
                    files={'file':
                           (
                               'test.xlsx',
                               open('test.xlsx', 'rb'),
                               'application/vnd.ms-excel',
                               {'Expires': '0'}
                           )
                    }
                    # headers={'Content-Type': 'multipart/form-data'}
                    )
# print(res.request.body)
print(res.text)
# print(res.request.headers)

结果:

print(res.request.body.decode('utf-8', 'ignore'))输出的请求原始数据:

还可以使用工具requests_toolbelt.MultipartEncoder

使用requests_toolbelt

import requests
from requests_toolbelt import MultipartEncoder

m = MultipartEncoder({'username': 'xiaoming', 'password': '123',
                      "file": open('test.xlsx', 'rb')})
res = requests.post(url='http://test/content_type.php',
                    data=m,
                    headers={'Content-Type': m.content_type}
                    )
# print(res.request.body.decode('utf-8', 'ignore'))
print(res.text)
# print(res.request.headers)

监控文件上传进度

服务端php代码:

<?
$value1 = $_POST["name"];
$value2 = $_POST["age"];
 
move_uploaded_file($_FILES["file1"]["tmp_name"],
    $_SERVER["DOCUMENT_ROOT"]."/uploadFiles/" . $_FILES["file1"]["name"]);
 
move_uploaded_file($_FILES["file2"]["tmp_name"],
    $_SERVER["DOCUMENT_ROOT"]."/uploadFiles/" . $_FILES["file2"]["name"]);
?>

客户端Python代码:

import requests
from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor


def my_callback(monitor):
    progress = (monitor.bytes_read / monitor.len) * 100
    print("\r 文件上传进度:%d%%(%d/%d)" % (progress, monitor.bytes_read, monitor.len), end=" ")


e = MultipartEncoder(
    fields={'username': 'xiaoming', "password": '123',
            'file1': ('1.png', open('logo.png', 'rb'), 'image/png'),
            'file2': ('2.png', open('logo.png', 'rb'), 'image/png')}
)

m = MultipartEncoderMonitor(e, my_callback)

r = requests.post('http://localhost/upload.php', data=m, headers={'Content-Type': m.content_type})
print(r.text)

正文是raw原始信息

text/xml

import requests

res = requests.post(url='http://test/content_type.php', data='<?xml ?>', headers={'Content-Type': 'text/xml'})
print(res.text)

application/json

import requests
import json

res = requests.post(url='http://test/content_type.php',
                    data=json.dumps({'key1': 'value1', 'key2': 'value2'}),
                    headers={'Content-Type': 'application/json'})
print(res.text)

或者:

import requests

res = requests.post(url='http://test/content_type.php',
                    json={'key1': 'value1', 'key2': 'value2'},
                    headers={'Content-Type': 'application/json'})
print(res.text)

参考

https://docs.python-requests/zh_CN/latest/
https://www.ietf/rfc/rfc1867.txt
https://atlee.ca/software/poster/ 适合python2
https://toolbelt.readthedocs.io/en/latest/
https://developer.mozilla/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types
https://developer.mozilla/zh-CN/docs/Web/HTTP/Headers/Content-Type

更多推荐

python3 Requests实现常见Content-Type请求