django之前-----web應用與框架
一web應用
web應用程序是一種可以通過Web訪問的應用程序,程序的最大好處是用戶很容易訪問應用程序,用戶只需要有瀏覽器即可,不需要再安裝其他軟件。應用程序有兩種模式C/S、B/S。
下面來看一個簡單的socket服務器
# -*- coding:utf-8 -*- import socket sk=socket.socket() sk.bind((‘127.0.0.1‘,8080)) sk.listen() while 1: conn,client_addr=sk.accept() conn.recv(1024) conn.send(b‘hello‘) conn.close() sk.close()
然後我們通過瀏覽器訪問,瀏覽器出現錯誤信息:該網頁無法正常運作
什麽原因呢?我們先來看看收到請求的輸出信息
![技術分享圖片](/img/jia.gif)
data b‘GET / HTTP/1.1\r\nHost: 127.0.0.1:8800\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\nCookie: csrftoken=IwhDDZ9RiKQUV4T5CbzGIhAcVZNxYuvAYdS7RKc0tmOmk02hHWfQ8sWnIGrN1pzC\r\n\r\nView Code‘
這個完整的信息裏面可以看到:最開始它有個http的頭部信息,這個是個標準,那麽我們試著去加入
改為
# -*- coding:utf-8 -*- import socket sk=socket.socket() sk.bind((‘127.0.0.1‘,8080)) sk.listen() while 1: conn,client_addr=sk.accept() conn.recv(1024) conn.send(b‘HTTP/1.1 200 OK\r\n\r\n‘) #需要一個http的頭 conn.send(b‘<h1>o98k</h1>‘) #發送的主體,也可以放入上面的那行 conn.close() sk.close()
現在訪問正常了,也能輸出我們要的信息
如果我們要根據用戶輸入的路徑訪問不同的頁面呢
1 我們可以做判斷,然後指向不同的函數
![技術分享圖片](/img/jia.gif)
# -*- coding:utf-8 -*- import socket sk=socket.socket() sk.bind((‘127.0.0.1‘,8080)) sk.listen() def home(url): return b"this is home page" def index(url): return b‘this is index home‘ while 1: conn,client_addr=sk.accept() data=conn.recv(1024) data_str=str(data,encoding=‘utf8‘) url=data_str.split(‘\r\n‘)[0].split()[1] print(url) print(‘=‘*30) if url==‘/index/‘: msg=index(url) elif url =="/home/": msg=home(url) else: msg=b"404!" conn.send(b‘HTTP/1.1 200 OK\r\n\r\n‘) #需要一個http的頭 conn.send(msg) #發送的主體,也可以放入上面的那行 conn.close() sk.close()View Code
2 我們可以將這些不同的頁面單獨拿出來(比如文件),然後指向他們
![技術分享圖片](/img/jia.gif)
# -*- coding:utf-8 -*- import socket sk=socket.socket() sk.bind((‘127.0.0.1‘,8080)) sk.listen() def home(url): with open("home.html",‘rb‘)as f: html_msg=f.read() return html_msg def index(url): return b‘this is index home‘ while 1: conn,client_addr=sk.accept() data=conn.recv(1024) data_str=str(data,encoding=‘utf8‘) url=data_str.split(‘\r\n‘)[0].split()[1] print(url) print(‘=‘*120) if url==‘/index/‘: msg=index(url) elif url =="/home/": msg=home(url) else: msg=b"404!" conn.send(b‘HTTP/1.1 200 OK\r\n\r\n‘) #需要一個http的頭 conn.send(msg) #發送的主體,也可以放入上面的那行 conn.close() sk.close()View Code
3 我們將他們優化一下,比如將要訪問的頁面放入一個列表,並且帶有一點動態網頁的效果
![技術分享圖片](/img/jia.gif)
# -*- coding:utf-8 -*- import socket import time sk=socket.socket() sk.bind((‘127.0.0.1‘,8080)) sk.listen() def home(url): with open("home.html",‘r‘)as f: html_msg=f.read() now=time.time() msg=html_msg.replace("uf;afsaf ",str(now)) return bytes(msg,encoding=‘utf8‘) def index(url): return b‘this is index home‘ def user(url): return b‘this is user page‘ url_func=[ (‘/index/‘,index), (‘/home/‘,home), (‘/user/‘,user), ] while 1: conn,client_addr=sk.accept() data=conn.recv(1024) data_str=str(data,encoding=‘utf8‘) url=data_str.split(‘\r\n‘)[0].split()[1] func=None for i in url_func: if i[0]== url: func=i[1] break if func: msg=func(url) else: msg=b"404!" conn.send(b‘HTTP/1.1 200 OK\r\n\r\n‘) #需要一個http的頭 conn.send(msg) #發送的主體,也可以放入上面的那行 conn.close() sk.close()View Code
這裏簡單說說http協議:
端口號80 ;HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,是用於萬維網(WWW:World Wide Web )服務器與本地瀏覽器之間傳輸超文本的傳送協議。
http協議的特點:
http協議是基於TCP/IP協議之上的應用層協議。
HTTP協議規定,請求從客戶端發出,最後服務器端響應該請求並 返回。換句話說,肯定是先從客戶端開始建立通信的,服務器端在沒有 接收到請求之前不會發送響應
HTTP是一種不保存狀態,即無狀態(stateless)協議。HTTP協議 自身不對請求和響應之間的通信狀態進行保存。也就是說在HTTP這個 級別,協議對於發送過的請求或響應都不做持久化處理。
服務器處理完客戶的請求,並收到客戶的應答後,即斷開連接。采用這種方式可以節省傳輸時間。這個是http協議無連接的特性
http協議的請求和響應
瀏覽器往服務端發的消息叫:請求(request) 請求行 GET /index/ HTTP/1.1 請求頭 k1:v1 \r\n 請求體 服務端回復給瀏覽器的消息叫:響應(response) 響應行 HTTP/1.1 200 OK\r\n 響應頭 Content-Type: text/html; charset=utf-8\r\n k2:v2\r\n ... \r\n 響應體 我們在瀏覽器上看到的內容
http的兩種請求方式 get post
GET提交的數據會放在URL之後,以?分割URL和傳輸數據,參數之間以&相連,如EditBook?name=test1&id=123456. POST方法是把提交的數據放在HTTP包的請求體中.
GET提交的數據大小有限制(因為瀏覽器對URL的長度有限制),而POST方法提交的數據沒有限制.
GET與POST請求在服務端獲取請求數據方式不同。
查看Pycharm控制臺,使用谷歌瀏覽器訪問一次網頁。實際上,是有2次請求的。
第一次,是正常請求。第二次是,favicon.ico請求,它是網頁圖標問題。這個請求,忽略即可。
GET的數據,是放到url後面的。POST數據是放在請求體後面的。
301重定向
永久性重定向。該狀態碼表示請求的資源已被分配了新的UR1,以後應使用資源現在所指的URI。也就是說,如果已經把資源對應的URI保存為書簽了,這時應該按Location首部字段提示的UR1重新保存。 像下方給出的請求URI,當指定資源路徑的最後忘記添加斜杠"/",就會產生301狀態碼。 http://example.com/sample
302重定向
臨時性重定向。該狀態碼表示請求的資源已被分配了新的URI,希望用戶(本次)能使用新的URI訪問。
和301MovedPermanently狀態碼相似,但302狀態碼代表的資源不是被永久移動,只是臨時性質的。換句話說,已移動的資源對應的URI將來還有可能發生改變。比如,用戶把URI保存成書簽,但不會像301狀態碼出現時那樣去更新書簽,
而是仍舊保留返回302狀態碼的頁面對應的URI。
web框架
一個web框架一般實現下面三個動能
總結: a. 接收瀏覽器發送的消息 b. 根據不同的路徑返回不同的內容 c. 通過字符串替換 實現 動態網頁 Python Web框架分類: 1. 框架自帶 a,b,c Tornado 2. 框架自帶b,c 使用第三方a Django 3. 框架自帶b,使用第三方的a和c Flask 另外一個維度的分類: 1. Django --> 大而全 2. 其他
django之前-----web應用與框架