中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

49web開發1_http_wsgiref

發布時間:2020-04-09 00:09:03 來源:網絡 閱讀:403 作者:chaijowin 欄目:編程語言

?

目錄

csbs... 1

http協議:... 2

http消息:... 3

Request... 3

常見傳遞信息的方式:... 3

Response... 4

wsgi... 5

wsgi app應用程序端:... 6

wsgi server服務器端:... 7

測試用命令:... 9

QUERY_STRING查詢字符串解析:... 9

?

?

?

web開發:

?

csbs

cs之間需使用socket,約定協議、版本(往往使用tcpudp),指定地址和端口,就可以通信;

cs傳輸數據,數據可以有一定的格式,雙方必須先約定好;

?

bs

b,一種特殊client,支持http(s)協議,能通過url向服務器發起請求,等待服務器端返回html等數據,并在browser內可視化展示的程序;

s,支持http(s),能接受眾多客戶端發起的http協議請求,經過處理,將html等數據返回給b

?

本質上,bs是一種特殊的cs

即客戶端必須是一種支持http協議且能解析并渲染html的軟件;

服務端必須是能接收多客戶端的http訪問的服務器軟件;

?

客戶端開發或前端開發;

服務端開發,py可學wsgidjangoflasktornado等;

?

pyweb框架:

早期cgi

wsgiweb server gateway interface,可看作是一種底層協議,它規定了服務器程序和應用程序各自實現什么接口,py的實現為wsgiref庫;

flask,基于wsgi,微框架;

django,基于wsgi,開源的web框架,巨無霸;

?

?

http協議:

無狀態的面向連接的協議;

?

無狀態,同一個客戶端的兩次請求,從服務端角度來說,它并不知道這兩個請求來自同一個客戶端;

解決:通過cookiesessiontoken)來判斷;

?

面向連接:

有連接,基于tcp是面向連接,需3次握手4次斷開;

短連接http1.0是一個請求一個連接,而tcp創建銷毀成本高,對server有很大影響;http1.1,支持keep-alive,默認開啟,一個連接打開后會保持一段時間(可設置),b再訪問該s就使用這個tcp連接,減輕了服務器壓力,提高了效率;

?

cookie

為解決http的無狀態,用到cookiesessionIDtoken);

一般,cookie信息是服務端生成,返回給客戶端的;

客戶端可自己設置cookie信息;

鍵值對信息,有時效;

browser發起每一個請求時,都會把cookie信息發給服務端;

是一種客戶端、服務端傳遞數據的技術;

服務端可通過判斷這些信息,來確定這次請求是否和之前的請求有關聯,服務端為了認識同一個client,用sessionIDtokensessionIDtoken可理解為是一種標識,這些標識要么通過cookie帶,要么通過url帶,要么通過request body帶;

?

注:

sessionID,保存在服務端內存中,隨著會話關閉而消亡;

token,替代sessionIDserver發給client的令牌,server通過此標識來認client

?

?

url組成:

uniform resource locator統一資源定位符,每一個鏈接指向一個資源供客戶端訪問;

schema://host[:port#]/path/.../[;url-params][?query-string][#anchor]

schema,模式、協議,httpftpfilemailtomysql等;

host:port80默認可不寫,有域名解析,實際上應該是IP

/path/to/resourcepath指向資源的路徑;

?key1=value1&key2=value2query string查詢字符串,問號分割,后面key=value形式且用&分割

?

?

http消息:

分為RequestResponse,請求和響應都由請求消息行(請求行)、header消息報頭、body消息正文組成;

?

Request

request method請求方法:

GET,請求獲取url對應的資源;

POST,提交數據至服務器端;

HEAD,和GET類似,不過不返回消息正文;

?

例:

? ?49web開發1_http_wsgiref

GET / HTTP/1.1?? #請求行,分別為:請求方法 請求路徑 協議版本CRLFCRLF為回車換行

Host:

User-Agent:

Accept:

Accept-Language:

Accept-Encoding:

Cookie:

Connection:

Upgrade-Insecure-Requests:?? #header消息報頭

?

body:?? #兩個CRLF后是body

?

?

常見傳遞信息的方式:

1GET方法使用query string

例:

http://www.magedu.com/python/index.html?id=5&name=python

?

2POST方法提交數據:

例:

http://127.0.0.1:9999/xxx/yyy?id=5&name=python

使用表單提交數據,文本框nameageweigthheight

請求消息如下:

POST /xxx/yyy?id=5name=python HTTP/1.1

HOST: 127.0.0.1:9999

content-length: 26

content-type: application/x-www-form-urlencoded

?

age=5&wegith=80&height=170

?

3url中本身就包含著信息:

http://www.magedu.com/python/student/001

?

注:

ajax就是用以上3種方式傳輸的,不過是異步方式;

?

客戶端傳參的幾種方式:

1、通過URL路徑傳遞,如http://ip:port/news/1/2,兩個參數,新聞類型id和頁碼;

2、通過query string傳遞,如http://ip:port/news?category=1&page=2

3、通過body請求體傳遞,又可根據數據格式分為k-v對、form數據、非form數據(json|xml);

4、通過http header傳遞;

?

?

Response

例:

49web開發1_http_wsgiref

HTTP/1.1 200 OK?? #響應消息行,依次為:協議版本 狀態碼 Message

?

status code狀態碼:

1XX,提示信息,表示請求已被成功接收,繼續處理;

2XX,表示正常響應;

???????? 200,正常返回了網頁內容;

???????? 201Created

3XX,重定向;

???????? 301,頁面永久性移走,永久重定向,返回新的urlb會根據返回的url發起新的request請求;

???????? 302,臨時重定向;

???????? 304,資源未修改,b使用本地緩存;

4XX,客戶端請求錯誤;

???????? 404Not Found,網頁找不到;

???????? 400,請求語法錯誤;

???????? 401,請求要求身份驗證;

???????? 403,服務器拒絕請求;

5XX,服務器端錯誤;

???????? 500,服務器內部錯誤;

???????? 502,上游服務器錯誤,如nginx反向代理時;

?

?

?

例,編寫類flask框架:

使用wsgi開發框架;

目的:

學習web框架的工作機制,了解眾多框架背后的技術;

學習API封裝,學習框架封裝的思想,并提供友好的編程接口;

?

注:

一般公司會直接使用類似于django這樣的框架,但一旦代碼規模到了一定階段,就需要對框架作二次開發,定制改版,所以了解框架背后的技術非常重要;

?

wsgi

49web開發1_http_wsgiref

wsgi,規定了服務器端和應用程序之間的接口;

請求、響應的數據都要經wsgi server轉發;

wsgi app看不到是哪個socket建立的連接(除非改wsgi接口);

?

wsgi app應用程序端:

1、應是一個可調用對象,py中應是函數、類、實現了__call__方法的類的實例;

2、這個可調用對象應接收2個參數,如

def application(environ,start_response):?? #函數實現

???????? return [res_str]

class Application:?? #類實現

???????? def __init__(self,environ,start_response):

?????????????????? pass

???????? def __iter__(self):

?????????????????? yield res_str

class Application:?? #類實現

???????? def __call__(self,environ,start_response):

?????????????????? return [res_str]

3、以上三種實現(三種都有用,框架簡單用函數,框架復雜用類多些,更復雜都用),必須返回一個可迭代對象;

?

environstart_response參數:

這兩個參數可以是任何合法名,一般默認用這兩個名字;

?

environ,是包含http請求信息的dict對象:

REQUEST_METHOD?? #請求方法,GETPOST

PATH_INFO?? #url中的路徑部分

QUERY_STRING?? #查詢字符串

SERVER_NAME,SERVER_PORT

HTTP_HOST?? #IP:PORT

SERVER_PROTOCOL?? #協議

HTTP_USER_AGENT?? #UserAgent信息,對互聯網公司非常重要,可對用戶作精準分析

?

start_response是一個可調用對象,有3個參數:

???????? start_response(status,response_headers,exc_info=None)?? #start_response應在返回可迭代對象前調用,因為它返回的是response header,而application返回的可迭代對象response body

status?? #狀態碼

response_headers?? #是一個元素為二元組列表,如[('Content-Type','text/plain;charset=utf-8')],用二元組模擬字典

exc_info?? #在錯誤處理時用

?

注:

'text/plain;charset=utf-8'

'text/html;charset=utf-8'?? #對中文開發,此處要通知browser使用的編碼,browser只認此處的通知,以讓b達到自動檢測編碼;chrome中工具-->編碼

'text/application;charset=utf8-8'

?

?

wsgi server服務器端:

需調用符合上述定義的可調用對象,傳入environstart_response,拿到返回的可迭代對象,返回給客戶端;

?

wsgiref

是一個wsgi參考實現庫,僅測試用,生產不能用

wsgiref.simple_server,實現一個簡單的wsgi http服務器;

?

from wsgiref import simple_server

simple_server.make_server(host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler):?? #啟動一個wsgi server

simple_server.demo_app(environ,start_response):?? #一個函數,小巧完整的wsgi app的實現

?

例:

from wsgiref.simple_server import make_server, demo_app

?

ip = '127.0.0.1'

port = 9999

?

server = make_server(ip, port, demo_app)

server.serve_forever()?? #server.handle_request()一次,Handle one request, possibly blocking.

server.shutdown()

server.server_close()

49web開發1_http_wsgiref

?

例:

from wsgiref.simple_server import make_server

?

def application(environ:dict, start_response):

??? print(type(environ))

??? html = '<h2>test</h2>'

??? start_response("200 OK", [('Content-Type', 'text/html; charset=utf-8')])

??? return [html.encode()]?? #encode()encode("utf-8")

?

ip = '127.0.0.1'

port = 9999

server = make_server(ip, port, application)

server.serve_forever()

server.shutdown()

server.server_close()

輸出:

<class 'dict'>

127.0.0.1 - - [10/Sep/2018 11:20:40] "GET / HTTP/1.1" 200 13

<class 'dict'>

127.0.0.1 - - [10/Sep/2018 11:20:40] "GET /favicon.ico HTTP/1.1" 200 13

?

chrome

工具-->編碼;

工具-->開發者工具-->Network,左側Name處點cn.bing.com,右側查看Headersview sourceview parsed

?

?

測試用命令:

curl -I http://ip:port/xxx?id=5?? #-I,使用HEAD方法

curl -X POST http://ip:port/yyy -d '{'x':2}?? #-X指定方法,-d傳輸數據

?

?

QUERY_STRING查詢字符串解析:

1、自己解析:

例:

def application(environ:dict, start_response):

??? qstr = environ.get('QUERY_STRING')

??? print(qstr)?? #拿到id=5&name=jowin

??? for pair in qstr.split('&'):

??????? k,_,v = pair.partition('=')

??????? print(k,v)

??? html = '<h2>test</h2>'

??? start_response("200 OK", [('Content-Type', 'text/html; charset=utf-8')])

??? return [html.encode()]

輸出:

id=5&name=jowin

id 5

name jowin

?

2、使用cgi模塊:

def parse_qs(qs, keep_blank_values=0, strict_parsing=0):

??? """Parse a query given as a string argument."""

??? warn("cgi.parse_qs is deprecated, use urllib.parse.parse_qs instead",

???????? DeprecationWarning, 2)

??? return urllib.parse.parse_qs(qs, keep_blank_values, strict_parsing)

cgi.parse_qs(qs)已過期,建議使用urllib.parse.parse_qs(qs)

例:

def application(environ:dict, start_response):

??? qstr = environ.get('QUERY_STRING')

??? print(qstr)

??? import cgi

??? print(cgi.parse_qs(qstr))?? #轉為dict

??? html = '<h2>test</h2>'

??? start_response("200 OK", [('Content-Type', 'text/html; charset=utf-8')])

??? return [html.encode()]

輸出:

id=5&name=jowin

{'id': ['5'], 'name': ['jowin']}

?

例:

def application(environ:dict, start_response):

??? qstr = environ.get('QUERY_STRING')

??? print(qstr)

??? from urllib.parse import parse_qs,parse_qsl

??? print(parse_qs(qstr))?? #dict;若query_string?id=5&name=jowin,tom,解析結果為{'name': ['jowin,tom'], 'id': ['5']},注意['jowin,tom']不是多值;若query_string?id=5&name=jowin&name=tom&age=&age=18,19,解析結果為{'name': ['jowin', 'tom'], 'id': ['5'], 'age': ['18,19']}

??? print(parse_qsl(qstr))?? #二元組列表;若query_string?id=5&name=jowin,tom,解析結果為[('id', '5'), ('name', 'jowin,tom')];若query_string?id=5&name=jowin&name=tom&age=&age=18,19[('id', '5'), ('name', 'jowin'), ('name', 'tom'), ('age', '18,19')]

??? html = '<h2>test</h2>'

??? start_response("200 OK", [('Content-Type', 'text/html; charset=utf-8')])

??? return [html.encode()]

輸出:

id=5&name=jowin

{'name': ['jowin'], 'id': ['5']}

[('id', '5'), ('name', 'jowin')]

?

?

?

?


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

钟山县| 沁源县| 新巴尔虎左旗| 亳州市| 新河县| 双流县| 准格尔旗| 赣榆县| 奎屯市| 赤城县| 儋州市| 湘潭县| 白城市| 历史| 南溪县| 分宜县| 讷河市| 浦北县| 锡林浩特市| 鹿泉市| 东乡县| 毕节市| 阿拉善右旗| 贵定县| 温州市| 隆安县| 清远市| 墨江| 潞城市| 盘锦市| 绥芬河市| 珠海市| 禹州市| 阿城市| 天祝| 广平县| 通化市| 阜康市| 大冶市| 夏河县| 宾川县|