国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

都9102年了,還問Session和Cookie的區(qū)別

Bowman_han / 2706人閱讀

摘要:前言最近看了一些同學(xué)的面經(jīng),發(fā)現(xiàn)無論什么技術(shù)崗位,還是會(huì)問到和的區(qū)別。所有學(xué)技術(shù)的同學(xué)都知道和函數(shù)怎么用,知道和的區(qū)別就是是儲(chǔ)存在服務(wù)端的,是存儲(chǔ)在瀏覽器的。的誕生是為了能讓無狀態(tài)的報(bào)文帶上一些特殊的數(shù)據(jù),讓服務(wù)端能夠辨識(shí)請(qǐng)求的身份。

1 前言

最近看了一些同學(xué)的面經(jīng),發(fā)現(xiàn)無論什么技術(shù)崗位,還是會(huì)問到 Session 和 Cookie 的區(qū)別。

所有學(xué)技術(shù)的同學(xué)都知道 Session 和 Cookie 函數(shù)怎么用,知道 Session 和 Cookie 的區(qū)別就是 Session 是儲(chǔ)存在服務(wù)端的,Cookie 是存儲(chǔ)在瀏覽器的。

但是實(shí)際上是什么東西,一些剛學(xué)習(xí)技術(shù)的同學(xué)估計(jì)還是模糊,我剛學(xué) PHP 的時(shí)候,這種感覺特別明顯。PHP 中 Session 和 Cookie 的操作只要操作 $_COOKIE$_SESSION 數(shù)組就可以了,而且操作方式和功能一模一樣,搞得我一臉懵逼。

最后,還是自己實(shí)現(xiàn)了一個(gè) Session 操作類才恍然大悟,實(shí)質(zhì)上就是兩個(gè)不同的存儲(chǔ)對(duì)象嘛。

2 Cookie

Cookie 的誕生是為了能讓無狀態(tài)的 HTTP 報(bào)文帶上一些特殊的數(shù)據(jù),讓服務(wù)端能夠辨識(shí)請(qǐng)求的身份。

對(duì)于 Cookie 的概念就不多說了,Cookie 說簡單點(diǎn)就是瀏覽器上的一個(gè) key-value 存儲(chǔ)對(duì)象,通過開發(fā)者工具直接看到 Cookie 的內(nèi)容(F12)

寫入數(shù)據(jù)方式

Cookie 寫入數(shù)據(jù)的方式是通過 HTTP 返回報(bào)文 Header 部分 Set-Cookie 字段來設(shè)置,一個(gè)帶有寫 Cookie 指令的的 HTTP 返回報(bào)文如下

HTTP/1.1 200 OK
Set-Cookie: SESSIONID=e13179a6-2378-11e9-ac30-fa163eeeaea1; Path=/
Transfer-Encoding: chunked
Date: Tue, 29 Jan 2019 07:12:09 GMT
Server: localhost

上述報(bào)文 Set-Cookie 指示瀏覽器設(shè)置 keySESSIONIDvaluee13179a6-2378-11e9-ac30-fa163eeeaea1 的 Cookie

獲取數(shù)據(jù)方式

瀏覽器在發(fā)送請(qǐng)求的時(shí)候會(huì)檢查當(dāng)前域已經(jīng)設(shè)置的 Cookie,在 HTTP 請(qǐng)求報(bào)文 Header 部分的 Cookie 字段里面帶上 Cookie 的信息。下面捉取了一段 HTTP 報(bào)文

GET http://10.0.1.24:23333/ HTTP/1.1
Host: 10.0.1.24:23333
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: SESSIONID=e13179a6-2378-11e9-ac30-fa163eeeaea1

從最后的 Cookie 字段看到,瀏覽器請(qǐng)求時(shí)帶上了 keySESSIONIDvaluee13179a6-2378-11e9-ac30-fa163eeeaea1 的數(shù)據(jù),后端直接解析 HTTP 報(bào)文就能獲取 Cookie 的內(nèi)容。

3 Session

Session 在代碼里面的語意是記錄客戶端狀態(tài)的一個(gè)存儲(chǔ)對(duì)象,是同一個(gè)客戶端請(qǐng)求共享的數(shù)組。這個(gè)存儲(chǔ)對(duì)象可以是文件、緩存系統(tǒng)、數(shù)據(jù)庫。

現(xiàn)在假設(shè)要使用 redis 來實(shí)現(xiàn) Session 功能,那么就要求瀏覽器每次請(qǐng)求都要帶一個(gè)相同的字符串作為身份信息,對(duì)應(yīng) redis 的 key,redis value 則為 Session 數(shù)組序列化的內(nèi)容。

那么如何讓瀏覽器每次請(qǐng)求都帶一個(gè)身份信息呢,這就是 Session 和 Cookie 的關(guān)系,通過 Cookie 傳遞這個(gè)身份信息。流程如下

客戶端請(qǐng)求

服務(wù)端檢查 Header,發(fā)現(xiàn)沒有 Cookie,于是生成一個(gè) UUID

服務(wù)端處理數(shù)據(jù),把部分?jǐn)?shù)據(jù)(登錄信息)存儲(chǔ)到 redis 里面,UUID 為 key,用戶 id 為 value

返回報(bào)文中,增加 Set-Cookie 字段,內(nèi)容帶上 UUID

瀏覽器收到報(bào)文,把 UUID 寫進(jìn)瀏覽器存儲(chǔ)里面

瀏覽器再次請(qǐng)求,帶上當(dāng)前的域的 Cookie,就是這個(gè) UUID

服務(wù)端通過 Cookie 字段獲取到該 UUID,去 redis 里面獲取用戶的信息

...

4 手動(dòng)實(shí)現(xiàn) Session

既然知道了 Session 的原理,我們手動(dòng)實(shí)現(xiàn)一個(gè) Session 操作類,采用文件保存的方式。http 框架采用 web.py,安裝方式如下

pip install web.py
Session類

我們要實(shí)現(xiàn)的這個(gè)類就叫 Session

class Session:

    def __init__(self):
        self.session_id = None
        # session 數(shù)組
        self._items = dict()
        self._load()

我們所有 session 文件放在 sessions 目錄下,文件名為對(duì)應(yīng)的 session id,內(nèi)容為 Session 數(shù)組序列化的字符串。在初始化對(duì)象的時(shí)候通過獲取名為 SESSIONID 的 Cookie,如果沒有就生成一個(gè)新的。

def _load(self):
    SESSIONID = web.cookies().get("SESSIONID", None)
    if not SESSIONID:
        SESSIONID = uuid.uuid()
    self.session_id = SESSIONID

    self._loadFromDisk()

獲取到 SESSIONID 后,檢查 sessions 目錄下有沒有對(duì)應(yīng)的文件,如果有就讀取并反序列化

def _loadFromDisk(self):
    """ 從文件加載 SESSION """
    file = "./sessions/%s" % self.session_id
    if os.path.exists(file):
        f = open(file, "rb")
        self._items = pickle.load(f)
        f.close()

獲取 Session 部分完成了,接下來就是保存 Session,我們要把 SESSIONID 寫進(jìn) Cookie 里面,這樣才能在下次請(qǐng)求時(shí)獲取到對(duì)應(yīng)的 SESSIONID

def _setSessionCookie(self):
    """ Session id 寫入 cookie """
    web.setcookie("SESSIONID", self.session_id)

最后把 Session 的內(nèi)容保存到文件里面

def _saveToDisk(self):
    """ 保存 SESSION 到文件 """
    f = open("./sessions/%s" % self.session_id, "wb")
    pickle.dump(self._items, f)
    f.close()
功能測(cè)試

我們新建一個(gè)文件,叫 server.py,寫入測(cè)試代碼

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 測(cè)試 session

import web
import time
from session import Session

urls = (
    "/", "index"
)

app = web.application(urls, globals())


class index:
    def GET(self):
        session = Session()
        if "login_time" not in session:
            session["login_time"] = int(time.time())
        return "login time: %s" % session["login_time"]


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

在同一目錄新建 session.py 文件,寫入 Session 類代碼

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Session

import os
import web
import uuid
try:
    import cPickle as pickle
except ImportError:
    import pickle


class Session:
    __instance = None

    def __new__(cls):
        """ 單例模式 """
        if cls.__instance is None:
            cls.__instance = object.__new__(cls)
            return cls.__instance
        else:
            return cls.__instance

    def __init__(self):
        self.session_id = None
        # session 數(shù)組
        self._items = dict()
        self._load()

    def __contains__(self, key):
        return key in self._items

    def __getitem__(self, key):
        return self._items.get(key, None)

    def __setitem__(self, key, value):
        self._items[key] = value
        return True

    def __delitem__(self, key):
        if key in self._items:
            del self._items[key]
        return True

    def __del__(self):
        """ 析構(gòu)函數(shù),結(jié)束請(qǐng)求時(shí)執(zhí)行 """
        self._setSessionCookie()
        self._saveToDisk()

    def _load(self):
        SESSIONID = web.cookies().get("SESSIONID", None)
        if not SESSIONID or SESSIONID is None:
            SESSIONID = uuid.uuid()
        self.session_id = SESSIONID

        self._loadFromDisk()

    def _loadFromDisk(self):
        """ 從文件加載 SESSION """
        file = "./sessions/%s" % self.session_id
        if os.path.exists(file):
            f = open(file, "rb")
            self._items = pickle.load(f)
            f.close()

    def _setSessionCookie(self):
        """ Session id 寫入 cookie """
        web.setcookie("SESSIONID", self.session_id)

    def _saveToDisk(self):
        """ 保存 SESSION 到文件 """
        f = open("./sessions/%s" % self.session_id, "wb")
        pickle.dump(self._items, f)
        f.close()

再在同一目錄新建 sessions 目錄,存放我們的 Session 文件

mkdir sessions

啟動(dòng)服務(wù)

[service@chengqm mysession]$ python server.py 23333
http://0.0.0.0:23333/

瀏覽器發(fā)起請(qǐng)求

查看 Cookie

查看 Session 文件內(nèi)容

[service@chengqm mysession]$ cat sessions/e13179a6-2378-11e9-ac30-fa163eeeaea1
(dp1
S"login_time"
p2
I1548749002
s.

可以多次刷新和更換瀏覽器測(cè)試,測(cè)試結(jié)果是符合我們對(duì) Session 的預(yù)期,簡陋版 Session 類功能就算實(shí)現(xiàn)了。

5 如果禁止 Cookie 是否可以獲取 Session

這是一道面試題,當(dāng)年竟然能用這個(gè)問題問倒過一些朋友,還是有些意思的

從前面可以知道,SESSIONID 是通過 Cookie 來傳遞,如果 Cookie 禁止了,還能獲取 SESSIONID 嗎? 答案是可以的

既然 Cookie 禁止了,那么我們就可以用參數(shù)的方法傳遞 SESSIONID,后端返回的時(shí)候,增加一個(gè)返回參數(shù),叫 SESSIONID,然后前端存儲(chǔ)到 localstorage 里面

前端請(qǐng)求的時(shí)候,去 localstorage 獲取SESSIONID,在請(qǐng)求參數(shù)里面增加這一個(gè)參數(shù)

后端 Session 處理,先嘗試從 Cookie 中獲取 SESSIONID,如果獲取不到,再嘗試從請(qǐng)求參數(shù)中獲取 SESSIONID

這樣,就算禁止 Cookie 也是能獲取 Session 的。

6 總結(jié)

最后,我們得出 Session 和 Cookie 區(qū)別和聯(lián)系

區(qū)別

Cookie 是瀏覽器端的存儲(chǔ)對(duì)象,有容量限制,通過 HTTP 報(bào)文與后端交互

Session 是服務(wù)端的存儲(chǔ)對(duì)象,實(shí)現(xiàn)的方式可以有文件系統(tǒng)、緩存系統(tǒng)、數(shù)據(jù)庫

聯(lián)系

Session 和 Cookie 都是為了實(shí)現(xiàn) HTTP 請(qǐng)求帶上客戶端狀態(tài)的方法

Session 大多數(shù)情況下都是依賴 Cookie 來傳遞 Session Id

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/43107.html

相關(guān)文章

  • 9102年了還問GETPOST區(qū)別

    摘要:前言最近看了一些同學(xué)的面經(jīng),發(fā)現(xiàn)無論什么技術(shù)崗位,還是會(huì)問到和的區(qū)別,而搜索出來的答案并不能讓我們裝得一手好逼,那就讓我們從報(bào)文的角度來擼一波,從而搞明白他們的區(qū)別。所以,和分開發(fā)送是部分瀏覽器或框架的請(qǐng)求方法,不屬于必然行為。 1 前言 最近看了一些同學(xué)的面經(jīng),發(fā)現(xiàn)無論什么技術(shù)崗位,還是會(huì)問到 get 和 post 的區(qū)別,而搜索出來的答案并不能讓我們裝得一手好逼,那就讓我們從 HT...

    h9911 評(píng)論0 收藏0
  • 9102年了,還不會(huì)Docker?10分鐘帶你從入門操作到實(shí)戰(zhàn)上手

    摘要:聯(lián)調(diào)測(cè)試,無需依賴他人。針對(duì)以上問題,有兩種解決方法,一個(gè)是自己搭建私有服務(wù),另一個(gè)是用云服務(wù)的鏡像管理平臺(tái)如阿里云的容器鏡像服務(wù)。利用,先對(duì)阿里云的服務(wù)進(jìn)行登錄。推送后,就能在阿里云的倉庫上看到這個(gè)鏡像。 Docker簡述 Docker是一種OS虛擬化技術(shù),是一個(gè)開源的應(yīng)用容器引擎。它可以讓開發(fā)者將應(yīng)用打包到一個(gè)可移植的容器中,并且該容器可以運(yùn)行在幾乎所有l(wèi)inux系統(tǒng)中(Windo...

    sf_wangchong 評(píng)論0 收藏0
  • 9102年了,Array數(shù)組方法趕緊用起來!

    摘要:示例使用作為深度,展開任意深度的嵌套數(shù)組會(huì)移除數(shù)組中的空項(xiàng)首先使用映射函數(shù)映射每個(gè)元素,然后將結(jié)果壓縮成一個(gè)新數(shù)組。注意對(duì)象數(shù)組不能使用方法來檢測(cè)。也就是返回值返回一個(gè)新的對(duì)象,該對(duì)象包含數(shù)組中每個(gè)索引的鍵值對(duì)。 showImg(https://segmentfault.com/img/remote/1460000019303737?w=651&h=289); 前言 寫久了業(yè)務(wù)代碼的我...

    genedna 評(píng)論0 收藏0
  • 18年求職面經(jīng)及總結(jié)

    摘要:年求職面經(jīng)及總結(jié)我的求職之路差不多走到盡頭了感覺真是精疲力盡了把這大半年的經(jīng)歷和面試總結(jié)寫下來希望能給和我一樣在求職路上煎熬的人一點(diǎn)幫助先說背景微電子科學(xué)與工程專業(yè)學(xué)過兩門和相關(guān)的課程語言和單片機(jī)這個(gè)專業(yè)的唯一好處就是大部分人并不知道這個(gè)專 18年求職面經(jīng)及總結(jié) 我的求職之路差不多走到盡頭了,感覺真是精疲力盡了.把這大半年的經(jīng)歷和面試總結(jié)寫下來,希望能給和我一樣在求職路上煎熬的人一點(diǎn)幫...

    zhangwang 評(píng)論0 收藏0
  • 18年求職面經(jīng)及總結(jié)

    摘要:年求職面經(jīng)及總結(jié)我的求職之路差不多走到盡頭了感覺真是精疲力盡了把這大半年的經(jīng)歷和面試總結(jié)寫下來希望能給和我一樣在求職路上煎熬的人一點(diǎn)幫助先說背景微電子科學(xué)與工程專業(yè)學(xué)過兩門和相關(guān)的課程語言和單片機(jī)這個(gè)專業(yè)的唯一好處就是大部分人并不知道這個(gè)專 18年求職面經(jīng)及總結(jié) 我的求職之路差不多走到盡頭了,感覺真是精疲力盡了.把這大半年的經(jīng)歷和面試總結(jié)寫下來,希望能給和我一樣在求職路上煎熬的人一點(diǎn)幫...

    fjcgreat 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<