亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
1.1 CBV 的基本使用

前面我們已經介紹了 CBV 的基本使用方法,其基本流程如下:定義視圖類 (TestView)該類繼承視圖基類 View,然后實現對應 HTTP 請求的方法。Django 在 View 類的基礎上又封裝了許多視圖類,如專門返回模板的 TemplateView 視圖類、用于顯示列表數據的 ListView 視圖類等等。這些封裝的是圖能夠進一步減少大家的重復代碼,后面我會詳細介紹這些封裝的視圖類的使用以及其源碼實現。# 代碼路徑 hello_app/views.py# ...class TestView(View): def get(self, request, *args, **kwargs): return HttpResponse('hello, get\n') def post(self, request, *args, **kwargs): return HttpResponse('hello, post\n') def put(self, request, *args, **kwargs): return HttpResponse('hello, put\n') def delete(self, request, *args, **kwargs): return HttpResponse('hello, delete\n') @csrf_exempt def dispatch(self, request, *args, **kwargs): return super(TestView, self).dispatch(request, *args, **kwargs)配置 URLConf,如下:# 代碼路徑 hello_app/urls.py# ...urlpatterns = [ path('test-cbv/', views.TestView.as_view(), name="test-cbv")]注意:不是直接寫視圖類,而是要調用視圖類的 as_view() 方法,這個 as_view() 方法返回的也是一個函數。啟動 Django 工程,測試:# 啟動django服務(django-manual) [root@server first_django_app]# python manage.py runserver 0.0.0.0:8888Watching for file changes with StatReloaderPerforming system checks...System check identified no issues (0 silenced).April 15, 2020 - 07:08:32Django version 2.2.11, using settings 'first_django_app.settings'Starting development server at http://0.0.0.0:8888/Quit the server with CONTROL-C# 打開另一個xshell窗口,發送如下請求[root@server ~]# curl -XGET http://127.0.0.1:8888/hello/test-cbv/hello, get[root@server ~]# curl -XPOST http://127.0.0.1:8888/hello/test-cbv/hello, post[root@server ~]# curl -XPUT http://127.0.0.1:8888/hello/test-cbv/hello, put[root@server ~]# curl -XDELETE http://127.0.0.1:8888/hello/test-cbv/hello, delete

2.2 auth_basic 模塊

auth_basic 模塊是基于 HTTP Basic Authentication 協議進行用戶名和密碼的認證,它默認是編譯進 Nginx 中的,可以在源碼編譯階段通過 --without-http_auth_basic_module 禁用該模塊。它的用法如下:Syntax: auth_basic string | off;# 默認是關閉的Default: auth_basic off;Context: http, server, location, limit_exceptSyntax: auth_basic_user_file file;Default: —Context: http, server, location, limit_except對于使用文件保存用戶名和密碼,二者之間需用冒號隔開,如下所示。# commentname1:password1name2:password2:commentname3:password3在 centos 系統上,想要生成這樣的密碼文件,我們可以使用 httpd-tools 工具完成,直接使用 yum install安裝即可。$ sudo yum install httpd-tools# 生成密碼文件user_file,帳號為user,密碼為pass$ htpasswd -bc user_file user pass接下來,我們只需要配置好 auth_basic 指令,即可對相應的 http 請求做好認證工作。

3.2 并行獲取 <a href="http://baidu.com">baidu.com</a>、<a href="http://taobao.com">taobao.com</a>、<a href="http://qq.com">qq.com</a> 首頁

編寫程序 parallel.py,該程序以并行的方式獲取 baidu、taobao、qq 的首頁,內容如下:from datetime import datetimeimport requestsimport threadingdef fetch(url): response = requests.get(url) print('Get %s: %s' % (url, response))time0 = datetime.now()t0 = threading.Thread(target = fetch, args = ("https://www.baidu.com/",))t1 = threading.Thread(target = fetch, args = ("https://www.taobao.com/",))t2 = threading.Thread(target = fetch, args = ("https://www.qq.com/",))t0.start()t1.start()t2.start()t0.join()t1.join()t2.join()time1 = datetime.now()time = time1 - time0print(time.microseconds)在第 5 行,定義了函數 fetch,函數 fetch 獲取指定 url 的網頁。在第 6 行,調用 requests 模塊的 get 方法獲取獲取指定 url 的網頁。在第 9 行,記錄執行的開始時間。在第 11 行到第 13 行,創建了 3 個線程,分別執行獲取 baidu、taobao、qq 的首頁。在第 14 行到第 16 行,啟動這 3 個線程,這 3 個線程并行執行。在第 17 行到第 19 行,等待這 3 個線程執行完畢。在第 21 行到第 23 行,記錄執行的結束時間,并計算總共花費的時間,time.micoseconds 表示完成需要的時間(微秒)。執行 parallel.py,輸出如下:Get https://www.baidu.com/: <Response [200]>Get https://www.qq.com/: <Response [200]>Get https://www.taobao.com/: <Response [200]>383800在輸出中,<Response [200]> 是服務器返回的狀態碼,表示獲取成功。成功獲取了 baidu、taobao、qq的首頁,總共用時為 383800 微秒。相比執行,串行執行總共用時為 683173 微秒,因此使用多線程加快了程序的執行速度。

HTTP 協議狀態碼-5XX

5XX 指的是請求出錯了,而且很有可能是服務端側的異常。下面定義的狀態碼有時候也只能反應一個大概情況,而不一定確切的,主要是協助用戶排查問題。

2. 301 Moved Permanently

請求的資源已經永久性的轉移了,新資源 URI 在頭部 Location指明,這時候如果瀏覽器有書簽,或者請求地址的緩存,最好都能替換成 Location 對應的值。HTTP/1.1 301 Moved PermanentlyLocation: https://www.imocc.com/http/301-moved-permanently

3. HttpUrlConnection 的使用步驟

首先還是引用一下 Google 官方的使用文檔:A URLConnection with support for HTTP-specific features. See the spec for details.Uses of this class follow a pattern:Obtain a new HttpURLConnection by calling [URL#openConnection()](https://developer.android.com/reference/java/net/URL#openConnection()) and casting the result to HttpURLConnection.Prepare the request. The primary property of a request is its URI. Request headers may also include metadata such as credentials, preferred content types, and session cookies.Optionally upload a request body. Instances must be configured with [setDoOutput(true)](https://developer.android.com/reference/java/net/URLConnection#setDoOutput(boolean)) if they include a request body. Transmit data by writing to the stream returned by [URLConnection.getOutputStream()](https://developer.android.com/reference/java/net/URLConnection#getOutputStream()).Read the response. Response headers typically include metadata such as the response body’s content type and length, modified dates and session cookies. The response body may be read from the stream returned by [URLConnection.getInputStream()](https://developer.android.com/reference/java/net/URLConnection#getInputStream()). If the response has no body, that method returns an empty stream.Disconnect. Once the response body has been read, the HttpURLConnection should be closed by calling [disconnect()](https://developer.android.com/reference/java/net/HttpURLConnection#disconnect()). Disconnecting releases the resources held by a connection so they may be closed or reused.官方文檔沒有對 Http 協議本身做什么解釋(如果對 Http 協議不太了解的同學,可以參考慕課網上網絡相關課程),主要是圍繞 HttpUrlConnection 的用法展開了一步步的描述,結合官網的解釋以及我個人的總結,大體上可以分為一下幾步:通過openConnection()方法創建一個HttpURLConnection:URL url = new URL(https://www.baidu.com);HttpURLConnection conn = (HttpURLConnection) url.openConnection();首先創建一個 URL 對象,參數就是我們要打開的地址,然后使用 url 對象的openConnection()來打開 Http 連接,拿到一個HttpURLConnection對象。2. 設置 Http 請求類型設置本次 Http 請求的方法類型,Http 有以下幾種類型:GETPOSTHEADCONNECTOPTIONSTRACEPATCHPUT**DELETE這里就不做詳細的解釋了,可自行百度。最常用的就是前兩種:GET和POST:conn.setRequestMethod("GET");設置 Http 相關參數這一步主要是設置請求頭的參數,我們前面那張大表就可以派上用場了。此時可以設置 Cookie、Content-Type、超時時間等等參數。比如設置超時時間為 3 秒:conn.setConnectTimeout(3*1000); conn.setWirteTimeout(3 * 1000);獲取輸入流通過getInputStream()方法獲取網絡輸入流,此后可以通過此對象獲取網絡數據,如下:InputStream in = conn.getInputStream();關閉流網絡流比較消耗資源,在使用完畢之后一定要將 Http 連接關掉:conn.disconnect();

3.1 資源

在一個論壇中,有兩種類型的資源:主題和回復,如下所示:資源URI主題http://www.bbs.com/topics/123回復http://www.bbs.com/anwers/456每個資源都有自己的 URI,/topics/123 是 id 為 123 的主題對應的 URI,/anwers/456 是 id 為 456 的回復對應的 URI。

2. 高可擴展性

Nginx 的架構設計是非常優秀的,極具擴展性,它完全由多個不同功能、不同層次、不同類型且耦合度極低的模塊組成。另外,我們還可以在官方提供的模塊上進行二次開發,例如 HTTP 模塊,其中設計了 HTTP 過濾器模塊,這樣我們開發一個新的 HTTP 模塊時,除了使用諸如 HTTP 核心模塊、events 模塊、log 模塊等不同層次的模塊,還可以原封不動地復用大量已有的 HTTP 過濾器模塊。這種低耦合度的優秀設計,造就了 Nginx 龐大的第三方模塊,而且 Nginx 的模塊都是嵌入到二進制的文件中執行的,這樣使得第三方模塊同樣具備極其優秀的性能,充分利用 Nginx 的高并發特性,因此許多高流量的網站都會在 Nginx 基礎上開發符合自己業務特性的定制模塊,而且開發成本低,效果好。另外,對于中小型企業來說,Nginx 開箱即用,其本身的高并發能力能滿足企業的大部分業務,因此 Nginx 在絕大部分互聯網企業中應用非常廣泛。

2. 格式

scheme 一般指的是協議,URI 的通用格式并沒有太多限制,一般是如下,以 scheme 開頭,冒號 “:” 分隔開。 <scheme>:<scheme-specific-part>雖然 URI 的格式沒怎么限制,但是不同 scheme 一般會遵循下面的格式來定義。<scheme>://<authority><path>?<query>以 scheme = http 加以說明: http://www.imocc.com:80/index.htm?id=3937Http 的 <authority>模塊一般不會寫在路徑上面,即使是 Basic Authorization 也是將用戶名密碼 base64(user:passwd) 寫在 head 里面。下面的例子說明 RUI 的一般用法:ftp://ftp.is.co.za/rfc/rfc1808.txt;gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles;http://www.math.uio.no/faq/compression-faq/part1.html;mailto:[email protected];news:comp.infosystems.www.servers.unix; telnet://melvyl.ucop.edu/0

3.1 在 Spring Security 開啟 X.509 客戶端認證

要在 Spring Security 項目中開啟 X.509 認證,只需要在 Http 的配置項中加入 x509,具體寫法如下:<http>... <x509 subject-principal-regex="CN=(.*?)," user-service-ref="userService"/>;</http>該對象有兩個可選配置項:subject-principal-regex,這是一個正則表達式,用戶來證書中解析出用戶名,其默認值為 CN=(.*?),,解析出的用戶名值將會傳給 UserDetailsService 用來獲得用戶權限;user-service-ref,該對象用來指定 UserDetailsService 實例,如果當前上下文只有一個 UserDetailsService 實例時,不需要指定此對象。

1. 前言

我們通常使用 Netty 來開發 TCP 協議,一般的應用場景都是客戶端和服務端長連接通訊的模式,其實,除了 TCP 協議之外 Netty 還支持其他常見的應用協議,比如:Http、WebSocket 等。我們所熟悉的 Tomcat 在 6.x 之后其實底層就是基于 Netty 去實現的。接下來我們主要講解如何通過 Netty 開發支持 Http 協議服務端,客戶端則是通過瀏覽器發起請求。

4. 運行程序

1. 在瀏覽器器中輸入 http://localhost:5000/get,顯示如下:初始化的狀態下,Session 為空,因此變量 user 的值為空。2. 在瀏覽器器中輸入 http://localhost:5000/set,顯示如下:在頁面 /set 的處理函數中,設置 Session 中名稱為 ‘user’ 的變量值為 ‘tom’,設置成功后,顯示名稱為 ‘user’ 的變量的值為 ‘tom’。3. 在瀏覽器器中輸入 http://localhost:5000/del,顯示如下:在頁面 /del 的處理函數中,刪除 Session 中名稱為 ‘user’ 的變量,刪除后,顯示名稱為 ‘user’ 的變量的值為空。4. 在瀏覽器器中輸入 http://localhost:5000/clear,顯示如下:在頁面 /clear 的處理函數中,刪除 Session 中所有的變量,刪除后,顯示名稱為 ‘user’ 的變量的值為空。

5.2 return 指令和 if 指令聯合使用

我們寫一個簡單配置如下:server { server_name return_and_if.test.com; listen 8008; root html; # 404錯誤跳轉到403.html頁面,根路徑由root指令指定 error_page 404 /403.html; # return 405 '405 Not Allowed!\n'; location / { if ( $request_method = POST ) { return 200 "Post Request!\n"; } }}先測試if指令,當請求方法為 POST 時,我們能得到 ‘post request!’ 這樣的字符串輸出。GET 請求時候,針對 404 情況,會跳轉到/403.html,我們準備一個 403.html 頁面,里面寫上’403, forbidden!’ 這一行內容,開始下面的 Http 請求:$ curl -XPOST http://180.76.152.113:8008 Post Request!$ curl http://180.76.152.113:8008/a.txt 403, forbidden!如果我們打開 return 405 這行指令,則 error_page 將不會生效,連同后面的 location 匹配也不會生效。無論我們發送如何請求,都會返回405的錯誤信息。這是因為 server 中的 return 指令是在 SERVER_REWRITE中執行的,而 location 匹配則是在下一個階段 FIND_CONFIG 中執行的,所以上一個階段在 return 后,根本不會進入后面的階段執行。$ curl http://180.76.152.113:8009 405 Not Allowed!

5. 304 Not Modified

一般是在有緩存的情況下,客戶端發起資源獲取請求,服務端判斷之前的資源未修改過,可以繼續使用緩存的資源。經常客戶端請求的頭部會帶上 If-None-Match If-Modified-Since If-Match 等帶有條件的頭部字段。客戶端GET /foo HTTP/1.1Accept: text/htmlIf-None-Match: "some-string"服務端HTTP/1.1 304 Not ModifiedETag: "some-string"

HTML5 SSE 瀏覽器發送事件

在遠古時代,網頁大都是靜態展示,服務器無需處理復雜且過多的請求,只需要靜靜地等待客戶端的請求,將 HTML 代碼通過 HTTP 的方式返回給客戶端。因此服務器也沒有主動推送數據給客戶端的能力,畢竟 HTTP 是無狀態的協議,即開即用。后來隨著互聯網的發展,服務端有一些即時消息需要立即展示給客戶端,早期的處理方式是通過客戶端定時發起 HTTP 請求,這種方式命中率較低且浪費服務端資源?,F在有了 HTML5 之后不需要那么麻煩了,可以使用 websocket 或者 SSE。SSE 全稱 server-sent events 單項消息傳遞事件,相對于 websocket 這種雙向協議,SSE 較為輕量,它只支持服務端向客戶端推送消息。

2.4 啟動項目

訪問 http://127.0.0.1:8080/hello ,效果如下:瀏覽器顯示返回數據

4.1 URL

/(http[s]?:\/\/)?[^\s(["<,>]*\.[^\s[",><]*/

Nginx 配置初步(下)

前面的學習,知道 Nginx 的配置規則如下:一行代表一個指令;每個指令有其上下文環境,比如 listen 指令只能在 http 指令塊中出現,不能單獨出現。下面我們將學習 Http 服務的初步配置和靜態服務資源配置:

2.2 Response

一般情況下,服務器收到客戶端的請求后,就會有一個 Http 的響應消息,Http 響應也由 4 部分組成,分別是:狀態行、響應頭、空行 和 響應實體。圖中的首部字段和返回內容(響應實體)中間是有一個空行的。

2.4. 網址框

把 input 的 type 設置為 url則表示網址框,那么輸入的內容會有規則限制,輸入的內容需要以 http:// 或者 https:// 開頭 ,且 @ 后必須有內容才滿足驗證規則,否則會有錯誤提示。代碼如下:<input type="url">Tips:這里的網站和我們平時輸入的網站不同,前面必須加上網絡協議,既 http:// 或者 https://

2. Django 中的 HttpRequest 類

上面我們初步接觸到了 HttpRequest 類,現在來詳細介紹下這個類及其相關屬性和方法。當 URLconf 文件匹配到客戶端的請求路徑后,會調用對應的 FBV 或者 CBV,并將 HttpRequest 類的實例作為第一個參數傳入對應的處理函數中。那么這個 HttpRequest 類有哪些常用的屬性和方法呢?常用屬性:HttpRequest.scheme:請求的協議,一般為 http 或者 https;HttpRequest.body:請求主體;HttpRequest.path: 所請求 URL 的完整路徑,即去掉協議,主機地址和端口后的路徑;HttpRequest.method:客戶端 HTTP 請求方法,如 GET、POST、PUT、DELETE等;HttpRequest.GET: 返回一個 querydict 對象,該對象包含了所有的 HTTP 請求中 GET 請求的參數;HttpRequest.POST: 返回一個 querydict 對象,該對象包含了所有的 HTTP 請求中 POST 請求的參數;HttpRequest.COOKIES:返回一個包含了所有 cookies 的字典;HttpRequest.FILES:返回一個包含所有文件對象的字典。常用方法:HttpRequest.get_host():返回客戶端發起請求的 IP + 端口;HttpRequest.get_port():返回客戶端請求端口;HttpRequest.get_full_path():返回請求的完整路徑,包括 “?” 后面所帶參數;HttpRequest.get_raw_uri():返回完整的 uri 地址,包括了協議、主機和端口以及完整請求路徑;HttpRequest.build_absolute_uri():通過 request 實例中的地址和變量生成絕對的 uri 地址。示例代碼:# 省略了import內容def hello_world(request, *args, **kwargs): request_info = "" request_info += "request.scheme={}\n".format(request.scheme) request_info += "request.body={}\n".format(request.body) request_info += "request.path={}\n".format(request.path) request_info += "request.method={}\n".format(request.method) request_info += "request.GET={}\n".format(request.GET) request_info += "request.FILES={}\n".format(request.FILES) request_info += "request.get_host={}\n".format(request.get_host()) request_info += "request.get_port={}\n".format(request.get_port()) request_info += "request.get_full_path={}\n".format(request.get_full_path()) request_info += "request.get_raw_uri={}\n".format(request.get_raw_uri()) request_info += "request.build_absolute_uri={}\n".format(request.build_absolute_uri()) return HttpResponse(request_info, content_type="text/plain")urlpatterns = [ path('admin/', admin.site.urls), path('hello/', hello_world),]我們啟動 Django 服務后,我們使用 curl 命令發送 HTTP 請求如下:# 準備一個新的文件[root@server ~]# cat upload_file.txt upload file test[root@server ~]# curl -XPOST "http://127.0.0.1:8881/hello/?a=xxx&a=yyy&b=zzz" -F 'data={"name": "join", "age": 28}' -F "file=@/root/upload_file.txt"request.scheme=httprequest.body=b'------------------------------c28860e155fe\r\nContent-Disposition: form-data; name="data"\r\n\r\n{"name": "join", "age": 28}\r\n------------------------------c28860e155fe\r\nContent-Disposition: form-data; name="file"; filename="upload_file.txt"\r\nContent-Type: text/plain\r\n\r\nupload file test\n\r\n------------------------------c28860e155fe--\r\n'request.path=/hello/request.method=POSTrequest.GET=<QueryDict: {'a': ['xxx', 'yyy'], 'b': ['zzz']}>request.FILES=<MultiValueDict: {'file': [<InMemoryUploadedFile: upload_file.txt (text/plain)>]}>request.get_host=127.0.0.1:8881request.get_port=8881request.get_full_path=/hello/?a=xxx&a=yyy&b=zzzrequest.get_raw_uri=http://127.0.0.1:8881/hello/?a=xxx&a=yyy&b=zzzrequest.build_absolute_uri=http://127.0.0.1:8881/hello/?a=xxx&a=yyy&b=zzz通過測試結果可以更容易理解 HttpRequest 類屬性和方法的含義。其中,上述 curl 請求中 -F 表示帶表單數據。

3.1 布局文件

放置一個占滿父布局的 WebView 在 ContentView 當中:<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <WebView android:id="@+id/webview" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentStart="true" android:layout_alignParentTop="true" /></RelativeLayout>這樣一來,后面整個頁面都會是 H5 頁面,就類似一個瀏覽器的效果。

3.1 Swagger Editor 快速入門

Swagger Editor 基本配置信息swagger: "2.0"info: description: "Swagger Editor Demo" version: "1.0.0" title: "Swagger Petstore" termsOfService: "http://swagger.io/terms/" contact: email: "[email protected]" license: name: "Apache 2.0" url: "http://www.apache.org/licenses/LICENSE-2.0.html"host: "petstore.swagger.io"basePath: "/v2"tags: name: "pet" description: "Everything about your Pets" externalDocs: description: "Find out more" url: "http://swagger.io"schemes: "https" "http"代碼解釋:swagger : 指名所使用的 Swagger 管理版本,這里只能寫 2.0 。info : 表示 Swagger Codegen 所生成的 Swagger-UI 界面的一些基本描述信息,上述包括 title(頭信息) 、 description(文檔描述) 、 version(文檔版本) 、termsOfService(服務團隊) 、 contact(聯系人) 、 license(協議或條款)。host : 表示生成的 Swagger-UI 所在的主機,即 Swagger-UI 界面生成之后是放在什么位置的。basePath : 表示訪問 Swagger-UI 生成界面的具體路徑。tags : 表示對 Swagger-UI 文檔中的接口進行分組。tags-description : 對接口分組添加描述信息。tags-externalDocs : 指定接口分組額外的說明文檔,這里沒有指定。tags-url : 表示對該接口分組添加額外的描述信息地址。schemes : 表示整個 Swagger-UI 界面上的接口所使用的網絡協議,這里指名可以使用 http 和 https 網絡協議。Swagger Editor 接口配置信息由于篇幅有限,Swagger Editor 接口配置信息部分的屬性介紹在 SpringBoot 集成 Swagger Codegen 這一小節中有詳細的說明,同學們可以去該小節了解。

2.3 適用場景

連接的建立需要開銷,頻繁的重建連接容易造成資源浪費,長連接適合客戶端和服務端都比較明確且傳輸數據比較大的情況;每臺服務器的連接數都是有限制的,如果太多的長連接阻塞會影響到新連接的建立。Http 是一種短連接的方式,這樣有利于他處理高并發的請求。有一種 slowHttp 的攻擊,就是利用 Http 協議的特點,故意制造了一個很長的報文,然后每次發送很少量的數據,使請求一直占用最終耗盡服務器的連接。所以 Http 雖然是短連接,但是一般是等到數據傳輸完成才斷開的,我們應該根據具體業務設置 Http 請求的超時時間。

2. 前端安全開發

前端的安全主要圍繞 W3C 進行,同時瀏覽器的漏洞和 Http 協議本身的缺陷也會造成影響。

2.2 SSL 和 TLS 的關系

我們常常聽到 HTTP + SSL = HTTPS 這樣的觀念,那 SSL 和 TLS 有什么關系呢?SSL 的全稱是 Secure Socket Layer,安全套接字層。SSL 最初用于 HTTP 加密傳輸,也就是 HTTPS 的早期形態,后來出現了 SSL v2 和 SSL v3,不過這兩個版本都有些瑕疵,于是出現了SSL v3.1,SSL v3.1 后該協議被重命名為 TLS,并從 1.0 從新編排版本,再往后出現了 v1.1、v1.2 和 v1.3。所以,從某種意義上講 SSL、SSL/TLS、TLS 這三種寫法的含義是相同的,我們多數情況還是把 HTTP 的安全框架稱為 SSL。

5. 運行程序

1. 在瀏覽器中輸入 http://localhost:5000/set_cookie,顯示如下:在頁面 /set_cookie 的處理函數中,服務端設置了名稱為 ‘mooc’、值為 ‘www.xianlaiwan.cn’ 的 Cookie,在客戶端使用 Javascript 正確顯示出 Cookie 的值。2. 在瀏覽器中輸入 http://localhost:5000/get_cookie,顯示如下:在頁面 /get_cookie 的處理函數中,服務端通過 request.cookies [‘imooc’] 獲取客戶端發送的 Cookie 的值,將 Cookie 的值返回給瀏覽器顯示。3. 在瀏覽器中輸入 http://localhost:5000/del_cookie,顯示如下:在頁面 /del_cookie 的處理函數中,服務端刪除名稱為 ‘mooc’ 的 Cookie,在客戶端使用 Javascript 顯示出 Cookie 的值為空。

4. 代碼實現

Netty 核心原理是對客戶端發送過來的數據進行解碼,以及給客戶端發送數據時需要進行數據的編碼。同樣的原理,Netty 對于 Http 協議的開發,其實也是針對 Http 格式是數據進行編碼和解碼而已,并沒有很多神奇的地方。當然我們對 Http 格式非常的熟悉,可以自己手工去實現這個復雜的過程,Netty 也考慮到了簡化開發的復雜度,因此給我們提供了相應的編解碼類。接下來,我們一起感受一下。

2.2 表述性 Represtation

資源是一種信息實體,在外界的具體呈現,可以有多種表述(或成為表現、表示)形式,在客戶端和服務端之間傳送的也是資源的表述,而不是資源本身。例如,文本資源可以采用 HTML、XML、JSON 等格式表現,圖片資源可以使用 PNG 或 JPG 等等格式表現。在 HTTP 協議中,客戶端可以通過 Accept 消息頭請求一種特定格式的表述,服務端則通過 Content-Type 告訴客戶端資源的表述形式。例如,在服務端存在資源 icon.png,客戶端請求資源 icon.png 的 HTTP 報文如下:GET /icon.png HTTP/1.1Host: www.example.comConnection: keep-aliveUser-Agent: Mozilla/5.0 AppleWebKit/537.36 Chrome/81.0Accept: text/html,image/png,*/*;...省略...在第 5 行,消息頭 Accept 描述客戶端希望接收的數據類型是 text/html 或者 image/png 格式。服務端收到請求報文后,響應客戶端如下:HTTP/1.1 200 OK server: nginx/1.14.0 (Ubuntu)date: Wed, 09 Sep 2020 07:52:21 GMTcontent-type: image/pngcontent-length: 194...省略...在第 4 行,消息頭 content-type 描述了響應報文中的數據類型是 image/png。

直播
查看課程詳情
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號