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请求方法包括:GETPOSTPUTDELETEHEADOPTIONSPATCHTRACE(已被禁用)、CONNECT。后文会详细介绍前7种方法。
  • 请求头部(Request Headers):主要包括请求元信息如HostUser-AgentContent-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-urlencodedmultipart/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/xmltext/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://www.mzph.cn/web/11838.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言指针详解(三)

目录 前言 一. 回调函数是什么&#xff1f; 1.定义 2. 代码示例&#xff1a;计数器 2.1 使用回调函数改造前 2.2 使用回调函数改造后 二. qsort使用举例 1. qsort介绍 2. 使用qsort函数排序整型数据 3. 使用qsort排序结构体数据 三. qsort函数的模拟实现 四. sizeo…

代码随想录:螺旋矩阵II相关题目推荐(54、LCR146)

59.螺旋矩阵II 题目 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。 示例 1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;[[1,2,3],[8,9,4],[7,6,5]] 代码&#xff08;新解法&am…

MyBatis——MyBatis 参数处理

一、单个简单类型参数 简单类型包括&#xff1a; byte short int long float double char Byte Short Integer Long Float Double Character String java.util.Date java.sql.Date parameterType 属性&#xff1a;告诉 MyBatis 参数的类型 MyBatis 自带类型自动推断机制…

LLM应用-prompt提示:生成搜索相关问题、生成回答格式包含参考资料

参考: https://isou.chat/ (AI回答与相关问题都是根据问题的搜索引擎结果结合大模型生成的) prompt参考: https://github.com/yokingma/search_with_ai/blob/6d32aa8f05f5f6ee12b5204787035b3f7797c22a/src/prompt.ts#L8 ##rag 根据搜索结果知识回答RagQueryPrompt = ` …

在Go语言中,可以这样使用Json

在Go语言中&#xff0c;处理JSON数据通常涉及编码&#xff08;将Go结构体转换为JSON字符串&#xff09;和解码&#xff08;将JSON字符串转换为Go结构体&#xff09;。Go标准库中的encoding/json包提供了这些功能。第三方插件可以使用"github.com/goccy/go-json"也有同…

Git | git log 和 git status 的区别

如是我闻&#xff1a; git log和git status是Git中的两个非常有用的命令&#xff0c;它们用于不同的目的&#xff0c;并提供不同类型的信息。 git log git log命令用于显示一个或多个分支的提交历史记录。这个命令会列出提交历史&#xff0c;包括每次提交的SHA-1哈希值、提交…

程控水冷阻性负载主要工作方式

程控水冷阻性负载是一种先进的电力设备&#xff0c;主要用于电力系统的测试和研究。它的主要工作方式是通过控制水冷系统的温度&#xff0c;来模拟不同的阻性负载条件&#xff0c;从而对电力设备进行各种性能测试。 首先&#xff0c;我们需要了解什么是阻性负载。阻性负载是指那…

博弈智能的特点

博弈智能是指通过算法和模型对博弈过程进行分析和决策的智能系统。在博弈中&#xff0c;各方参与者追求自身利益和目标&#xff0c;会采取各种策略来达到自己的目标。其中&#xff0c;包括了一些不正当手段&#xff0c;如诡计和欺骗&#xff08;诡&#xff09;&#xff08;诈&a…

代码随想录算法训练营Day 42| 动态规划part04 | 01背包问题理论基础I、01背包问题理论基础II、416. 分割等和子集

代码随想录算法训练营Day 42| 动态规划part04 | 01背包问题理论基础I、01背包问题理论基础II、416. 分割等和子集 文章目录 代码随想录算法训练营Day 42| 动态规划part04 | 01背包问题理论基础I、01背包问题理论基础II、416. 分割等和子集01背包问题理论基础一、01背包问题二、…

WSL设置启动时自动启动docker服务或其他服务

方式一: Windows系统的WSL,当windows关机再开机后,WSL等于是重新开机的,默认情况下,不会启动Docker服务。例如在Ubuntu 22.04中,需要使用命令 service docker start来启动。由于我习惯关机断电,因此每天开机打开WSL后都要手动输入这个命令,非常麻烦。所以找了一个方法…

Redis教程——哨兵

在上篇文章我们学习了Redis教程——主从复制&#xff0c;这篇文章我们学习Redis教程——哨兵监控。 在主从复制中如果主机发生宕机&#xff0c;从机Redis会一直等到主机的恢复&#xff0c;这样会导致只能进行读操作&#xff0c;不能进行写操作&#xff0c;这大大降低了系统的高…

资料同化 | 搭建docker环境-1

Community Gridpoint Statistical Interpolation (GSI) system DTC 是一个分布式设施&#xff0c;NWP 社区可以在这里测试和评估用于研究和操作的新模型和技术。 DTC的目标包括&#xff1a; 链接研究和操作社区 研究成果转化为实际操作的速度 加快改善天气预报 开发和测试有…

Cocos Creator 3.8.x 透明带滚动功能的容器

ScrollView 是一种带滚动功能的容器 1、删除ScrollView下Sprite组件的SpriteFrame 2、ScrollView下scrollBar的Sprite组件的Color设为&#xff1a;FFFFFF00 3、ScrollView下view的Graphics组件的FillColor设为&#xff1a;FFFFFF00

IP代理如何帮助SEO进行优化?

IP代理在SEO优化中扮演着重要的角色&#xff0c;它通过多种方式帮助提升网站的搜索排名和可见性。以下是IP代理如何帮助SEO进行优化的详细阐述&#xff1a; 第一点&#xff0c;数据采集与分析&#xff1a;在SEO过程中&#xff0c;大量的数据是必不可少的。通过使用IP代理&…

如何区分os.walk()与os.scandir()

os.walk() import os for dirpath, dirname, files in os.walk(./):# dirpath 当前——路径# dirname 当前——路径——下——文件夹名——列表# files 当前——路径——下——文件——列表dirpath 当前路径 ./ dirname 当前路径下面文件夹名称组成的列表&#xff0c;共3个文…

c++ std::shared_ptr学习

背景 c中智能指针shared_ptr用于自动管理资源&#xff0c;通过引用计数来记录资源被多少出地方使用。在不使用资源时&#xff0c;减少引用计数&#xff0c;如果引用计数为0&#xff0c;表示资源不会再被使用&#xff0c;此时会释放资源。本文记录对c中std::shared_ptr的源码学习…

攻防世界PHP2

1、打开靶机链接http://61.147.171.105:49513/&#xff0c;没有发现任何线索 2、尝试访问http://61.147.171.105:49513/index.php&#xff0c;页面没有发生跳转 3、尝试将访问 尝试访问http://61.147.171.105:49513/index.phps index.php 和 index.phps 文件之间的主要区别在于…

GNU Radio创建时间戳 C++ OOT块

文章目录 前言一、创建自定义的 C OOT 块1、创建 timestamp_sender C OOT 模块①、创建 timestamp_sender OOT 块②、修改 C 代码 2、创建 timestamp_receiver C OOT 模块①、创建 timestamp_receiver OOT 块②、修改 C 代码 3、创建 delayMicroSec C OOT 模块①、创建 delayMi…

Vue3实战笔记(20)—封装头部导航组件

文章目录 前言一、封装头部导航栏二、使用步骤总结 前言 Vue 3 封装头部导航栏有助于提高代码复用性、统一风格、降低维护成本、提高可配置性和模块化程度&#xff0c;同时还可以实现动态渲染等功能&#xff0c;有利于项目开发和维护。 一、封装头部导航栏 封装头部导航栏&am…

HFSS学习-day4-建模操作

通过昨天的学习&#xff0c;我们已经熟悉了HFSS的工作环境&#xff1b;今天我们来讲解HFSS中创建物体模型的县体步骤和相关操作。物体建模是HFSS仿真设计工作的第一步&#xff0c;HFSS中提供了诸如矩形、圆面、长方体圆柱体和球体等多种基本模型(Primitive)&#xff0c;这些基本…