03-01 HTTP請求


![](https://img2018.cnblogs.com/blog/1825659/201910/1825659-20191009222056510-25731790.png)

1 請求報文和響應報文

打開瀏覽器,當我們輸入一個url,點擊訪問的時候會向目標服務器發送一個HTTP請求,請求的的時候會發生什么呢,會經過os七層,這里我們不贅述os七層通訊原理,可以理解為通過url我們請求目標服務器的一段具體的資源,可以理解為發送了一個請求,一個請求的本質就是向目標服務器上面發送了一些數據,這種瀏覽器於服務器之間交互的數據被稱為報文。

![](https://img2018.cnblogs.com/blog/1825659/201910/1825659-20191009222110932-1793891022.png)
  • 請求報文:請求時瀏覽器發送的數據稱為請求報文

  • 響應報文:服務器收到了請求返回給瀏覽器的數據稱為響應報文

    ✔提示:這里我們們是BS架構去講解, BS架構就是瀏覽器和后端服務器的交互,CS架構是客戶端和服務端的交互,BS架構可以理解為CS架構的一個具體實現。瀏覽器就是客戶端,后端服務器就是服務端。

![](https://img2018.cnblogs.com/blog/1825659/201910/1825659-20191009222123126-61992503.png)

報文中的GET請求和POST請求

  • GET提交的數據會放在URL之后,以?分割URL和傳輸數據,參數之間以&相連,如EditBook?name=test1&id=123456.
  • POST方法是把提交的數據放在HTTP包的請求體中.
  • GET提交的數據大小有限制(因為瀏覽器對URL的長度有限制)
  • POST方法提交的數據沒有限制。
  • GET與POST請求在服務端獲取請求數據方式不同。

報文實例:

	'''
    GET請求報文
    # 請求首行
    GET / HTTP/1.1\r\n
    # get請求后面的參數
    GET /?name=lqz&age=18 HTTP/1.1\r\n
    # 請求頭
    Host: 127.0.0.1:8008\r\n
    Connection: keep-alive\r\n
    Cache-Control: max-age=0\r\n
    Upgrade-Insecure-Requests: 1\r\n
    User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36\r\n
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate, br\r\n
    Accept-Language: zh-CN,zh;q=0.9\r\n
    Cookie: csrftoken=7xx6BxQDJ6KB0PM7qS8uTA892ACtooNbnnF4LDwlYk1Y7S7nTS81FBqwruizHsxF\r\n\r\n'
    # 請求體(get請求,請求體為空)    
    '''
    '''
    
    
    
    
    POST請求報文
    # 請求首行
    POST /?name=lqz&age=18 HTTP/1.1\r\n
    # 請求頭
    Host: 127.0.0.1:8008\r\nConnection: keep-alive\r\n
    Content-Length: 21\r\nCache-Control: max-age=0\r\n
    Origin: http://127.0.0.1:8008\r\nUpgrade-Insecure-Requests: 1\r\n
    Content-Type: application/x-www-form-urlencoded\r\n
    User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36\r\n     					   Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nReferer: http://127.0.0.1:8008/?name=lqz&age=18\r\n
    Accept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\nCookie: csrftoken=7xx6BxQDJ6KB0PM7qS8uTA892ACtooNbnnF4LDwlYk1Y7S7nTS81FBqwruizHsxF\r\n\r\n
    # 請求體
    name=lqz&password=123'
    
    '''
![](https://img2018.cnblogs.com/blog/1825659/201910/1825659-20191009222153150-801230202.png)

2 request對象

2.1什么是request對象?

request對象封裝解析了請求報文中的數據,其大部分功能是由依賴包werkzeug完成的,並且每個request對象都是線程隔離的,保證了數據的安全性。

2.2為什么要有request對象?

request對象解決了很多問題,各種請求的方法以及請求參數的格式都不一致,所以flask幫我們做了一個request對象,專門去解析各種方法以及各種格式的請求,以便於去開發使用。

2.3 requst對象的常用方法

request對象使用需要從flask模塊中導入

from flask import Flask, request
2.3.1 使用request屬性獲取url

訪問: http://127.0.0.1:5000/student_list/?name=mark :

表2-1 使用request的屬性獲取url

屬性 解析值 屬性 解析值
path u‘/student_list/’ base_url u'http://127.0.0.1:5000/student_list/'
full_path u‘/student_list/?name=mark’ url u'http://127.0.0.1:5000/student_list/?name=mark'
host u'127.0.0.1:5000' url_root u'http://127.0.0.1:5000/'
host_url u'http://127.0.0.1:5000/'

request的解析結果如下。

@app.route('/student_list/')
def student_list():
    print(request.path)          # 輸出 /student_list/
    print(request.full_path)     # 輸出 /student_list/?name=mark
    print(request.host)          # 輸出 127.0.0.1:5000
    print(request.host_url)      # 輸出 http://127.0.0.1:5000/
    print(request.base_url)      # 輸出 http://127.0.0.1:5000/student_list/
    print(request.url)           # 輸出 http://127.0.0.1:5000/student_list/?name=mark
    print(request.url_root)      # 輸出 http://127.0.0.1:5000/

    return 'request.urldemo測試'
2.3.2 其他request對象常用的屬性和方法。
![](https://img2018.cnblogs.com/blog/1825659/201910/1825659-20191009222230423-1742169751.png)

request里面有諸多的方法,先對requests這些方法有個初步印象,隨着我們日后的學習會慢慢接觸到這些request常用的方法。

![](https://img2018.cnblogs.com/blog/1825659/201910/1825659-20191009222243838-1757971982.png)

3 GET和post的實例:

3.1 常見的HTTP方法見下表:

請求 說明 請求 說明
GET 獲取服務器資源 DELETE 刪除服務器資源
POST 處理服務器資源 PATCH 在服務器更新資源(客戶端提供改變的屬性)
PUT 在服務器更新資源(客戶端提供改變后的完整資源)

一般常用的請求為GET和POST

3.2 GET請求:

![](https://img2018.cnblogs.com/blog/1825659/201910/1825659-20191009222432221-608582097.jpg)

GET請求一般用於在服務器上獲取資源,不會更改服務器的狀態。

GET實例

@app.route('/', methods=['GET'])  # 不寫methods也可以 默認就接收get請求
def demo_get():
    print(request.args.get('name'))  # 輸出 mark
    
    return '{}請求'.format(request.method)

結合request對象,使用request.args屬性獲取get傳來的參數,關於args我們在上一章已經論述過了。

關鍵詞

  • 使用request.args屬性獲取get傳來的參數,關於args我們在上一章已經論述過了。
  • @app.route('/', methods=['GET']) 指定瀏覽器只能以GET方法訪問服務端。

3.3 POST請求:

POST 請求: 會給服務器提交一些數據或者文件,會對服務器的狀態產生影響。

在了解POST請求之前我們先了解一下render_termplate

3.3.1 render_template的簡單使用
from flask import Flask, request, render_template

我們暫時只簡單的理解render_template模塊可以把html文件返回給瀏覽器並渲染。

如:

![](https://img2018.cnblogs.com/blog/1825659/201910/1825659-20191009222510737-1061015223.png)

server.py

from flask import Flask, request, render_template
...
@app.route('/login/',methods=['GET'])
def login():
    return render_template('login.html')	
...

注意:render_template()會去flask根目錄下的templates里面尋找文件,所以給的參數路徑是相對路徑。

關鍵詞:render_template()中放的文件路徑是與templates文件夾相對的路徑

templates/login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄界面</title>
</head>
<body>
<form action="/login_request/" method="POST">
    用戶:<input type="text" name="username">
    密碼:<input type="text" name="password">
    <input type="submit" value="提交">
</form>
</body>
</html>

關鍵詞

  • form標簽的action指定的是跳轉的頁面。並且會自動拼接成http://127.0.0.1:5000/login_request/

    ​ 也就是本項目的: ip地址+端口+/login_request/

  • form標簽的method指定的是以什么方法請求服務端,此案例中請求的方法為POST方法。

訪問127.0.0.1:5000/login/ 后如下圖

![](https://img2018.cnblogs.com/blog/1825659/201910/1825659-20191009222556143-340794981.png)
3.3.2 正式開始我們的POST案例:

項目目錄:

server.py

from flask import Flask, request, render_template
import config

app = Flask(__name__)


@app.route('/login_request/',methods=['POST'])
def login_request():
    print(request.form.get('username'))  # 'mark'
    print(request.form.get('password'))  # '123'
    if request.form.get('username') == 'mark' and request.form.get('password') == '123':
        return 'success'
    else:
        return 'error'

@app.route('/login/',methods=['GET'])
def login():
    return render_template('login.html')


if  __name__ == '__main__':
    app.run()

關鍵詞

  • request.form是專門用來針對表單取數據的,在這里如果前端是以表單的形式提交的,我們可以使用request.form來取值
  • @app.route() 中的 methods=['POST'] 代表只接收瀏覽器的POST請求

templates/login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄界面</title>
</head>
<body>
<form action="/login_request/" method="POST">
    用戶:<input type="text" name="username">
    密碼:<input type="text" name="password">
    <input type="submit" value="提交">
</form>
</body>
</html>

![](https://img2018.cnblogs.com/blog/1825659/201910/1825659-20191009222657669-1682091996.png)
![](https://img2018.cnblogs.com/blog/1825659/201910/1825659-20191009222717747-459163041.png)
![](https://img2018.cnblogs.com/blog/1825659/201910/1825659-20191009222737192-1944613716.jpg)

總體的邏輯是 :

  1. 首先訪問127.0.0.1:5000/login/,默認是get請求。
  2. 然后return render_template('login.html') 返回給瀏覽器頁面。
  3. 然后填寫內容點擊提交,以post方式請求 http://127.0.0.1:5000/login_request/。
  4. 然后進入def login_request()視圖函數 進行邏輯判斷返回成功與否。

3.4 一個視圖函數同時可以接收GET和POST請求

我們的案例和3.3.2案例完成的業務邏輯是一樣的,相當於簡化了3.3.2的案例,把兩個視圖函數合並到一起,利用request.method屬性可以獲取字符串格式的請求方法。來區分本次請求是GET還是POST

實例:

server.py

from flask import Flask, request, render_template
import config

app = Flask(__name__)

@app.route('/login_inner/',methods=['POST','GET'])
def login_inner():
    if request.method == 'GET': #判斷本次請求是否為get請求
        return render_template('login.html')
    if request.form.get('username') == 'mark' and request.form.get('password') == '123':
        return 'success'
    return 'error'

if  __name__ == '__main__':
    app.run(debug=True)

關鍵詞

  • @app.route()methods方法 指定該視圖函數接收瀏覽器傳過來的請求方法,可以指定多個。
  • request.method獲取字符串格式的請求方法

templates/login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄界面</title>
</head>
<body>
<form action="" method="POST">  
    用戶:<input type="text" name="username">
    密碼:<input type="text" name="password">
    <input type="submit" value="提交">
</form>
</body>
</html>

其展示效果

![](https://img2018.cnblogs.com/blog/1825659/201910/1825659-20191009222809137-31438223.png)
![](https://img2018.cnblogs.com/blog/1825659/201910/1825659-20191009222826146-1144854374.png)
![](https://img2018.cnblogs.com/blog/1825659/201910/1825659-20191009222856655-1365629759.png)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM