HTTP协议及Python实现
最近的项目需要频繁在前后端之间传输数据,本篇主要介绍HTTP协议以及数据传输方法。
1 HTTP协议
1.1 http协议简介
HTTP(Hypertext Transfer Protocol)是一种用于传输超文本数据的应用层协议。它是万维网上数据交换的基础,定义了客户端和服务器之间进行通信的规则。这里需要注意以下几点:
- 超文本数据:指的是在网络上通过HTTP协议传输的HTML文档或其他超文本数据,可以包含文本、图片、链接、多媒体等元素,用于构建网页内容。
- 客户端:发送HTTP请求想向服务端请求特定的资源或执行特定的资源,通常是指浏览器、移动应用、命令行工具(如
curl)或其他通过HTTP发送请求的程序。 - 服务端:接收并处理HTTP请求,根据请求的内容执行相应的操作,最后将结果封装在HTTP响应中返回给客户端。
1.2 http请求
http请求是由客户端程序自动设置的,而不需要用户手动设置。一个完整的http请求主要包含以下信息:
- 请求行(Request Line):包括请求方法、请求的资源路径和HTTP协议版本。例如:
GET /index.html HTTP/1.1。目前常用的http请求方法包括:GET、POST、PUT、DELETE、HEAD、OPTIONS、PATCH、TRACE(已被禁用)、CONNECT。后文会详细介绍前7种方法。 - 请求头部(Request Headers):主要包括请求元信息如
Host、User-Agent、Content-Type等。 - 空行:请求头部与请求体之间必须有一个空行来表示头部的结束。
- 请求体(Request Body):在某些请求中可能包含请求体,用于传输请求的数据,如 POST、PUT 请求。请求体的内容取决于具体的请求类型和应用需求。
http请求样例如下:
POST /api/login HTTP/1.1
Host: www.example.com
Content-Type: application/json
Content-Length: 36{"username": "user123", "password": "pass456"}
1.3 http响应
HTTP 响应通常包含了服务端对客户端请求的回应信息,其中包括状态行、响应头部和响应体等组成部分。
- 状态行:主要包含http协议版本、状态码和状态信息(与状态码相关的可读性描述)。常用的http响应的状态码及状态信息主要有:
200 OK(请求成功)、301 Moved Permanently(永久重定向)、302 Found(临时重定向)、400 Bad Request(错误请求)、401 Unauthorized(未授权)、403 Forbidden(禁止访问)、404 Not Found(未找到)、500 Internal Server Error(内部服务器错误)和503 Service Unavailable(服务不可用)。 - 响应头部:包含了多个响应头字段,例如 Date、Content-Type 和 Content-Length 等。
- 空行:用于分隔响应头部和响应体。
- 响应体:HTTP 响应体主要包含了服务器返回给客户端的实际数据或资源,其内容取决于具体的请求和服务器处理结果。
一个http响应样例如下(这里的响应体是一段html格式):
HTTP/1.1 200 OK
Date: Wed, 18 May 2024 12:00:00 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 127<!DOCTYPE html>
<html>
<head><title>Example Page</title>
</head>
<body><h1>Hello, World!</h1>
</body>
</html
Tips: http请求和响应的头部信息中都可以添加用户自定义的设置。
1.4 请求体/响应体
HTTP协议的请求体和响应体的数据类型并不完全一致,但相差不大,请求头和响应头中的Content-Type通常用来设定数据类习惯。常见的数据类型主要包括以下几种:
- 表单数据:该类型通常采用
application/x-www-form-urlencoded或multipart/form-data编码。这种类型通常使用键值对的形式提交数据,常用于提交表单数据。举例如下(只展示必要信息, 下同)
Content-Type: application/x-www-form-urlencodedusername=user123&password=pass456
- JSON数据:该类型常用于 Web API,通常使用
application/json编码。举例如下:
Content-Type: application/json{"username": "user123", "password": "pass456"}
- XML数据:该类型常用于传输结构化数据,常采用
application/xml或text/xml编码。举例如下:
Content-Type: application/xml<user><username>user123</username><password>pass456</password>
</user>
- 纯文本数据。举例如下:
Content-Type: text/plain
Content-Length: 23This is a text message.
- 二进制数据: 任意格式的二进制数据,如图片、音频、视频等。举例如下:
Content-Type: multipart/form-data; boundary=boundary123--boundary123
Content-Disposition: form-data; name="image"; filename="example.jpg"
Content-Type: image/jpeg[这里是二进制数据,表示图片文件的内容]
--boundary123--
2 HTTP请求方法
2.1 GET
GET请求通过URL传递参数,并且参数会显示在URL的查询字符串中,因此适用于传输较少的数据,比如请求页面、查询数据等。其URL(资源请求路径,即客户端请求的资源在服务端上的位置或标识。)举例如下:
http://example.com/api/user?id=123
在这个URL中,http://example.com/api/user是请求的资源在服务端上的地址,id=123是GET请求所要传递给服务端的参数,服务端收到GET请求后,解析URL中的参数,根据参数执行相应的操作。
GET请求通常用于查询数据,并且因为为URL长度有限,所以不适合传输大量数据。
2.2 POST
POST方法是一种用于向服务器提交数据的请求方法。相比GET请求,POST请求通常使用请求体向服务器端传输更多、更复杂的数据,比如表单提交、文件上传等。其常用的URL结构如下:
http://example.com/api/register
与GET请求相比,POST请求不是幂等的,即多次发送相同的POST请求,可能会导致服务器状态的变化,比如重复提交表单会创建多条数据。
2.3 PUT/PATCH
PUT和PATCH方法都可以实现对服务器资源的更新,PUT可以实现全局更新,而PATCH可以实现局部更新。PATCH请求使用与PUT请求相同的URL结构,用于指定要更新的资源。其URL举例如下:
http://example.com/api/user/123
在这个URL案例中,123是要更新的用户的唯一标识符。而要更新的数据可以放在请求体中。资源的唯一标识符通常由请求的 URL 来定义。
2.4 DELETE
DELETE请求可以删除指定资源。它允许客户端从服务器上删除指定的资源。
2.5 HEAD
HEAD请求是一种类似于GET请求的请求方法,但是服务器在响应中只返回头信息,不返回实体主体。HEAD请求通常用于获取目标资源的元数据,而不需要获取资源的实际内容。而服务器收到HEAD请求后,依然会执行相应的处理逻辑。但服务端不会返回实体主体,只返回头信息,这样可以节省带宽和处理时间。
2.6 OPTIONS
OPTIONS 方法是一种用于询问服务器支持的请求方法和其他资源相关信息的请求方法之一。当客户端发送 OPTIONS 请求时,服务器会返回一个描述了资源的通用信息的响应。
2.7 Python实现
虽然 HTTP 协议是一种通用的协议,但不同的编程语言都有自己的库和工具集来处理网络通信和HTTP请求。这里仅以Python为例说明:
server.py
from flask import Flask, request, make_response
app = Flask(__name__)userlist=[['1',"admin","12345678"]]
@app.route('/login', methods=['GET','HEAD'])
def login():username = request.args.get('username')password = request.args.get('password')response=make_response()response.headers['Content-Type'] = 'text/plain'for user in userlist:if user[1] == username and user[2] == password:response.status_code=200response.data='登陆成功'breakelse:response.status_code=400response.data='登陆失败'return response@app.route('/register', methods=['POST'])
def register():username = request.form.get('username')password = request.form.get('password')len_1=len(userlist)response=make_response()response.headers['Content-Type'] = 'text/plain'try:userlist.append([str(len_1+1),username,password])response.status_code=200response.data='注册成功'except:response.status_code=400response.data='注册失败'return response@app.route('/updatepassword/<user_id>', methods=['PUT','PATCH'])
def updatepassword(user_id): response=make_response()response.headers['Content-Type'] = 'text/plain'password=request.args.get('password')for user in userlist:if user[0] == user_id:user[2]=passwordresponse.status_code=200response.data='修改成功'breakelse:response.status_code=400response.data='修改失败'return responseif __name__ == '__main__':app.run(port=5000, debug=True)print(userlist)
client.py
from flask import Flask, request, make_response
app = Flask(__name__)userlist=[['1',"admin","12345678"]]
@app.route('/login', methods=['GET','HEAD'])
def login():username = request.args.get('username')password = request.args.get('password')response=make_response()response.headers['Content-Type'] = 'text/plain'for user in userlist:if user[1] == username and user[2] == password:response.status_code=200response.data='登陆成功'breakelse:response.status_code=400response.data='登陆失败'return response@app.route('/register', methods=['POST'])
def register():username = request.form.get('username')password = request.form.get('password')len_1=len(userlist)response=make_response()response.headers['Content-Type'] = 'text/plain'try:userlist.append([str(len_1+1),username,password])response.status_code=200response.data='注册成功'except:response.status_code=400response.data='注册失败'return response@app.route('/updatepassword/<user_id>', methods=['PUT','PATCH'])
def updatepassword(user_id): response=make_response()response.headers['Content-Type'] = 'text/plain'password=request.args.get('password')for user in userlist:if user[0] == user_id:user[2]=passwordresponse.status_code=200response.data='修改成功'breakelse:response.status_code=400response.data='修改失败'return responseif __name__ == '__main__':app.run(port=5000, debug=True)print(userlist)
结果:
登陆失败
注册成功
{'Server': 'Werkzeug/2.2.3 Python/3.11.5', 'Date': 'Mon, 13 May 2024 13:02:22 GMT', 'Content-Type': 'text/plain', 'Content-Length': '12', 'Connection': 'close'}
修改成功
修改成功
相关文章:
HTTP协议及Python实现
最近的项目需要频繁在前后端之间传输数据,本篇主要介绍HTTP协议以及数据传输方法。 1 HTTP协议 1.1 http协议简介 HTTP(Hypertext Transfer Protocol)是一种用于传输超文本数据的应用层协议。它是万维网上数据交换的基础,定义了客户端和服务器之间进行通…...
【机器学习】逻辑化讲清PCA主成分分析
碎碎念:小编去年数学建模比赛的时候真的理解不了主成分分析中的“主成分”的概念!!但是,时隔两年,在机器学习领域我又行了,终于搞明白了!且看正文!再分享一个今天听到的播客中非常触…...
Vue常见的指令
Vue.js 提供了许多内置指令,这些指令可以在模板中用于处理元素的显示、行为等。以下是 Vue.js 中常见的 7 个指令及其详细代码示例: 1、v-bind:用于属性绑定,可以动态更新 HTML 属性。 html<template> <div> <img…...
【Ansible】ansible-playbook剧本
playbook 是ansible的脚本 playbook的组成 1)Tasks:任务;通过tasks 调用ansible 的模板将多个操作组织在一个playbook中运行 2)Variables:变量 3)Templates:模板 4)Handles…...
Linux的命令
; 昨天学习了七个命令,分别是:cd命令(切换目录)、pwd命令(当前目录)、mkdir命令(创建目录)、touch命令(创建文件)、date命令(显…...
No known conditions for “./lib/locale/lang/zh-cn“ entry in “element-plus“ pa
yarn的安装和卸载 npm install -g yarn npm uninstall yarn -g //yarn卸载 改用yarn卸载试试 先安装yarn npm install -g yarn 卸载掉原来的element-plus yarn remove element-plus 重新安装原有的element-plus版本 yarn add element-plus2.3.1 低版本页面引用为 i…...
实验名称:TCP 连接管理
目录 前言 TCP报文段格式 TCP建立连接 TCP释放连接 实验目的 实验原理 实验步骤 1. 启动WireShark,设置抓包状态 2. 访问指定服务器 ,通过Wireshark抓取通信数据报文 3. 分析TCP连接建立的三次握手和连接释放的四次握手过程 原始数据记录 实验…...
go语言map底层及扩容机制原理详解(上)
底层数据结构-哈希表 go语言map的底层数据结构是哈希表:通过哈希表来存储键值对,通过hash函数把键值对散列到一个个桶(bucket)中。 什么是哈希表? 在顺序结构以及平衡树中,元素与其的存储位置之间没有对应关系,因此…...
互联网职场说 | “领导找我谈话,原来是给我涨薪,但却只涨了200,还偷偷叮嘱我保密,这次只给我涨了薪”
职场中,一般当领导找你谈话时,心里总是会涌起两种心理活动:问责和表扬。不过很多人第一反应就是有点担心害怕,其次才会想有什么好事临到我了! 一位职场网友分享说,有天领导忽然找她谈话,当时心…...
Android 如何启用user版本的adb源码分析
Android调试桥(ADB, Android Debug Bridge)是一个Android命令行工具,包含在SDK 平台工具包中,adb可以用于连接Android设备,或者模拟器,实现对设备的控制,比如安装和调试应用。和Appium一样,adb也是基于C/S架…...
linux phpstudy 重启命令
[rootLinuxWeb phpstudy]# ./system/phpstudyctl restart 查看命令 1) phpstudy -start 启动小皮面板 2) phpstudy -stop 停止小皮面板 3) phpstudy -restart 重启小皮面板 4) phpstudy -status 查询面板状态 5) phpstudy -in…...
台式电脑屏幕亮度怎么调节?让你的眼睛更舒适!
在日常使用台式电脑时,调节屏幕亮度是一项常见的需求。不同的环境和个人偏好可能需要不同的亮度设置。因此,了解台式电脑屏幕亮度怎么调节是非常重要的。本文将介绍三种常见的方法,帮助您轻松调节台式电脑屏幕亮度,以满足您的需求…...
打造安全的 Linux 环境:实用配置指南
唠唠闲话 一开始接触服务器,我只是把它当博客的托管网站,源文件用 GitHub 备份,所以网站被黑了也没啥关系。但随着使用深入,网站逐渐加入我的日常工作流中,而且有了使用更多服务的需求。在这种情况下,服务…...
神经网络有哪些算法
神经网络算法是人工智能领域的重要组成部分,它通过模拟人类神经系统的结构和功能,实现对复杂问题的处理和分析。以下是对神经网络算法的详细概述,包括常见的算法和它们的特点、应用等,力求达到约2500字的篇幅。 一、神经网络算法概述 神经网络算法是一种基于人工神经元的…...
计算机网络期末试题
第一章 概述 一. 单选题(共13题,36.4分) 1. (单选题) 因特网起源于( )网络。 A. ARPANETB. EthernetC. CATVD. CERNET 我的答案: A:ARPANET;正确答案: A:ARPANET; 2.8分 2. (单选题)人们把( )年作为因特网的诞…...
Unity学习笔记---图层
渲染层级 1,调整Sprite Renderer中的Order in Layer可以调整图层层级。 2,在Edit--Project Setting--Graphics中,调整TransParency Sort Mode为Custom Axis, 并将TransParency Sort Axis中的Z值默认的1改为0,将Y改为…...
【简单探索微软Edge】
🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…...
YOLOv5独家改进:backbone改进 | 微软新作StarNet:超强轻量级Backbone | CVPR 2024
💡💡💡创新点:star operation(元素乘法)在无需加宽网络下,将输入映射到高维非线性特征空间的能力,这就是StarNet的核心创新,在紧凑的网络结构和较低的能耗下展示了令人印象深刻的性能和低延迟 💡💡💡如何跟YOLOv5结合:替代YOLOv5的backbone 收录 YOL…...
概率密度函数pdf的某种解释与洞察
1.一个想法实验 我在想一个数,姑且称之为X,介于0和10之间(含0和10)。如果我不告诉你别的,你会想象X = 0的概率是多少?X = 4?假设我对任何特定的数字都没有偏好,你会想象十一个整数0,1,2,.….,10也是一样。因为所有的概率加起来必须是1,所以逻辑上的结论是给11个选项…...
【OceanBase诊断调优】—— 转储错误(错误代码 4138/ORA-01555)
当读事务很长时,租户进行转储会报 4138/ORA-01555 错误。本文介绍该错误的处理方法。 适用版本 OceanBase 数据库 V2.X 及以后的版本 问题现象 当读事务很长,租户进行转储时会出现以下错误。 Oracle 租户: ORA-01555:snapsho…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...
