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.pswp.cn/web/11838.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/11838.shtml
英文地址,請注明出處:http://en.pswp.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;這些基本…