Django中使用Cookie,Session以及自定義分頁

一句惯、Cookie

  • Cookie的介紹

1.Cookie的由來
大家都知道HTTP協(xié)議是無狀態(tài)的雨膨。

無狀態(tài)的意思是每次請求都是獨立的淹冰,它的執(zhí)行情況和結(jié)果與前面的請求和之后的請求都無直接關(guān)系购啄,它不會受前面的請求響應情況直接影響,也不會直接影響后面的請求響應情況肪获。

一句有意思的話來描述就是人生只如初見,對服務器來說柒傻,每次的請求都是全新的孝赫。

狀態(tài)可以理解為客戶端和服務器在某次會話中產(chǎn)生的數(shù)據(jù),那無狀態(tài)的就以為這些數(shù)據(jù)不會被保留红符。會話中產(chǎn)生的數(shù)據(jù)又是我們需要保存的青柄,也就是說要“保持狀態(tài)”。因此Cookie就是在這樣一個場景下誕生预侯。

2.什么是Cookie
Cookie具體指的是一段小信息致开,它是服務器發(fā)送出來存儲在瀏覽器上的一組組鍵值對,下次訪問服務器時瀏覽器會自動攜帶這些鍵值對萎馅,以便服務器提取有用信息双戳。

3.Cookie的原理
cookie的工作原理是:由服務器產(chǎn)生內(nèi)容,瀏覽器收到請求后保存在本地糜芳;當瀏覽器再次訪問時飒货,瀏覽器會自動帶上Cookie,這樣服務器就能通過Cookie的內(nèi)容來判斷這個是“誰”了峭竣。

4.查看Cookie
我們使用Chrome瀏覽器塘辅,打開開發(fā)者工具。

cookie

  • Django中操作Cookie

1. 獲取Cookie

request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)

參數(shù):

  • default: 默認值
  • salt: 加密鹽
  • max_age: 后臺控制過期時間

2. 設(shè)置Cookie

rep = HttpResponse(...)
rep = render(request, ...)

rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密鹽', max_age=None, ...)
return rep

參數(shù):

  • key, 鍵
  • value='', 值
  • max_age=None, 超時時間
  • expires=None, 超時時間(IE requires expires, so set it if hasn't been already.)
  • path='/', Cookie生效的路徑皆撩,/ 表示根路徑扣墩,特殊的:根路徑的cookie可以被任何url的頁面訪問
  • domain=None, Cookie生效的域名
  • secure=False, https傳輸
  • httponly=False 只能http協(xié)議傳輸,無法被JavaScript獲取(不是絕對呻惕,底層抓包可以獲取到也可以被覆蓋)

3. 刪除Cookie

def logout(request):
    rep = redirect("/login/")
    rep.delete_cookie("user")  # 刪除用戶瀏覽器上之前設(shè)置的usercookie值
    return rep

示例盘榨,使用cookie驗證登錄:

#這個是用來裝飾需要校驗的頁面
def check_login(func):
    @wraps(func)    #這里用wraps裝飾方法是python內(nèi)置的,目的是為了保持被裝飾方法原有的調(diào)用不變
    def inner(request, *args, **kwargs):
        next_url = request.get_full_path()
        if request.get_signed_cookie("login", salt="SSS", default=None) == "yes":
            # 已經(jīng)登錄的用戶...
            return func(request, *args, **kwargs)
        else:
            # 沒有登錄的用戶蟆融,跳轉(zhuǎn)剛到登錄頁面
            return redirect("/login/?next={}".format(next_url))
    return inner

def login(request):
    if request.method == "POST":
        username = request.POST.get("username")
        passwd = request.POST.get("password")
        if username == "xxx" and passwd == "dashabi":
            next_url = request.GET.get("next")
            if next_url and next_url != "/logout/":
                response = redirect(next_url)
            else:
                response = redirect("/class_list/")
            response.set_signed_cookie("login", "yes", salt="SSS")
            return response
    return render(request, "login.html")


@check_login
def logout(request):
    rep = redirect("/login/")
    rep.delete_cookie("login")  # 刪除用戶瀏覽器上之前設(shè)置的cookie值
    return rep

@check_login
def index(request):
    return render(request, "index.html")

二草巡、Session

  • Session的介紹

Cookie雖然在一定程度上解決了“保持狀態(tài)”的需求,但是由于Cookie本身最大支持4096字節(jié)型酥,以及Cookie本身保存在客戶端山憨,可能被攔截或竊取,因此就需要有一種新的東西弥喉,它能支持更多的字節(jié)郁竟,并且他保存在服務器,有較高的安全性由境。這就是Session棚亩。

問題來了,基于HTTP協(xié)議的無狀態(tài)特征虏杰,服務器根本就不知道訪問者是“誰”讥蟆。那么上述的Cookie就起到橋接的作用。

我們可以給每個客戶端的Cookie分配一個唯一的id纺阔,這樣用戶在訪問時瘸彤,通過Cookie,服務器就知道來的人是“誰”笛钝。然后我們再根據(jù)不同的Cookie的id质况,在服務器上保存一段時間的私密資料,如“賬號密碼”等等玻靡。

總結(jié)而言:Cookie彌補了HTTP無狀態(tài)的不足结榄,讓服務器知道來的人是“誰”;但是Cookie以文本的形式保存在本地囤捻,自身安全性較差臼朗;所以我們就通過Cookie識別不同的用戶,對應的在Session里保存私密的信息以及超過4096字節(jié)的文本最蕾。

另外依溯,上述所說的Cookie和Session其實是共通性的東西,不限于語言和框架瘟则。


  • Django中操作Session

1. 基操

request.session['k1']   # 獲取k1的值黎炉,不存在則報錯
request.session.get('k1',None)  # 獲取k1的值,不存在則返回None
request.session['k1'] = 123     # 不存在則創(chuàng)建醋拧,存在則更新
request.session.setdefault('k1',123)    # 不存在則創(chuàng)建默認值慷嗜,存在則不作操作
del request.session['k1']   # 刪除k1

鍵淀弹,值,鍵值對操作
request.session.keys()  # 提取所有鍵
request.session.values()    # 提取所有值
request.session.iterkeys()  # 迭代鍵
request.session.itervalues()    # 迭代值
request.session.iteritems() # 迭代鍵值
request.session.session_key     # 用來獲取session字符串
request.session.clear_expired()     # 清除所有已超過自身設(shè)定超時時間的session
request.session.exists('session_key')   # 檢查session字串在數(shù)據(jù)庫中是否存在
request.session.delete('session_key')   # 刪除當前用戶的所有session數(shù)據(jù)
request.session.clear()     # 清除用戶的所有session數(shù)據(jù)庆械,用于注銷

# 刪除當前的會話數(shù)據(jù)并刪除會話的Cookie薇溃。
request.session.flush() 
    這用于確保前面的會話數(shù)據(jù)不可以再次被用戶的瀏覽器訪問
    例如,django.contrib.auth.logout() 函數(shù)中就會調(diào)用它缭乘。

request.session.set_expiry(value): 設(shè)置session超時時間沐序,默認2周
    # 如果value是個整數(shù),session會在value秒后失效,
    # 如果value是個datatime或timedelta堕绩,session會在這個時間后失效
    # 如果value是0策幼,用戶關(guān)閉游覽器session會失效
    # 如果value是None,session會依賴全局session失效策略

2. Session流程解析

session流程

3. Django中的Session配置
Django中默認支持Session,其內(nèi)部提供了5種類型的Session供開發(fā)者使用奴紧。

1. 數(shù)據(jù)庫Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默認)

2. 緩存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
SESSION_CACHE_ALIAS = 'default'                            
# 使用的緩存別名(默認內(nèi)存緩存特姐,也可以是memcache),此處別名依賴緩存的設(shè)置

3. 文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
SESSION_FILE_PATH = None                                    
# 緩存文件路徑黍氮,如果為None唐含,則使用tempfile模塊獲取一個臨時地址tempfile.gettempdir() 

4. 緩存+數(shù)據(jù)庫
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎

5. 加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎

其他公用設(shè)置項:
SESSION_COOKIE_NAME = "sessionid"                       
# Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串(默認)
SESSION_COOKIE_PATH = "/"                              
 # Session的cookie保存的路徑(默認)
SESSION_COOKIE_DOMAIN = None                             
# Session的cookie保存的域名(默認)
SESSION_COOKIE_SECURE = False                            
# 是否Https傳輸cookie(默認)
SESSION_COOKIE_HTTPONLY = True                           
# 是否Session的cookie只支持http傳輸(默認)
SESSION_COOKIE_AGE = 1209600                             
# Session的cookie失效日期(2周)(默認)
SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  
# 是否關(guān)閉瀏覽器使得Session過期(默認)
SESSION_SAVE_EVERY_REQUEST = False                       
# 是否每次請求都保存Session沫浆,默認修改之后才保存(默認)

4. Session版登陸驗證

from functools import wraps


def check_login(func):
    @wraps(func)
    def inner(request, *args, **kwargs):
        next_url = request.get_full_path()
        if request.session.get("user"):
            return func(request, *args, **kwargs)
        else:
            return redirect("/login/?next={}".format(next_url))
    return inner


def login(request):
    if request.method == "POST":
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")

        if user == "alex" and pwd == "alex1234":
            # 設(shè)置session
            request.session["user"] = user
            # 獲取跳到登陸頁面之前的URL
            next_url = request.GET.get("next")
            # 如果有捷枯,就跳轉(zhuǎn)回登陸之前的URL
            if next_url:
                return redirect(next_url)
            # 否則默認跳轉(zhuǎn)到index頁面
            else:
                return redirect("/index/")
    return render(request, "login.html")


@check_login
def logout(request):
    # 刪除所有當前請求相關(guān)的session
    request.session.delete()
    return redirect("/login/")


@check_login
def index(request):
    current_user = request.session.get("user", None)
    return render(request, "index.html", {"user": current_user})

5. 補充:CBV加session驗證裝飾器
CBV實現(xiàn)的登錄視圖

class LoginView(View):

    def get(self, request):
        """
        處理GET請求
        """
        return render(request, 'login.html')

    def post(self, request):
        """
        處理POST請求 
        """
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        if user == 'alex' and pwd == "alex1234":
            next_url = request.GET.get("next")
            # 生成隨機字符串
            # 寫瀏覽器cookie -> session_id: 隨機字符串
            # 寫到服務端session:
            # {
            #     "隨機字符串": {'user':'alex'}
            # }
            request.session['user'] = user
            if next_url:
                return redirect(next_url)
            else:
                return redirect('/index/')
        return render(request, 'login.html')

要在CBV視圖中使用我們上面的check_login裝飾器,有以下三種方式:
from django.utils.decorators import method_decorator
1. 加在CBV視圖的get或post方法上

from django.utils.decorators import method_decorator

class HomeView(View):

    def dispatch(self, request, *args, **kwargs):
        return super(HomeView, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return render(request, "home.html")
    
    @method_decorator(check_login)
    def post(self, request):
        print("Home View POST method...")
        return redirect("/index/")

2. 加在dispatch方法上
因為CBV中首先執(zhí)行的就是dispatch方法件缸,所以這么寫相當于給get和post方法都加上了登錄校驗铜靶。

from django.utils.decorators import method_decorator

class HomeView(View):

    @method_decorator(check_login)
    def dispatch(self, request, *args, **kwargs):
        return super(HomeView, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return render(request, "home.html")

    def post(self, request):
        print("Home View POST method...")
        return redirect("/index/")

3. 直接加在視圖類上,但method_decorator必須傳 name 關(guān)鍵字參數(shù)
如果get方法和post方法都需要登錄校驗的話就寫兩個裝飾器他炊。

from django.utils.decorators import method_decorator

@method_decorator(check_login, name="get")
@method_decorator(check_login, name="post")
class HomeView(View):

    def dispatch(self, request, *args, **kwargs):
        return super(HomeView, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return render(request, "home.html")

    def post(self, request):
        print("Home View POST method...")
        return redirect("/index/")

CSRF Token相關(guān)裝飾器在CBV只能加到dispatch方法上,或者加在視圖類上然后name參數(shù)指定為dispatch方法已艰。
備注:

  • csrf_protect痊末,為當前函數(shù)強制設(shè)置防跨站請求偽造功能,即便settings中沒有設(shè)置全局中間件哩掺。
  • csrf_exempt凿叠,取消當前函數(shù)防跨站請求偽造功能,即便settings中設(shè)置了全局中間件嚼吞。
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator


class HomeView(View):

    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(HomeView, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return render(request, "home.html")

    def post(self, request):
        print("Home View POST method...")
        return redirect("/index/")

或者:

from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.utils.decorators import method_decorator

@method_decorator(csrf_exempt, name='dispatch')
class HomeView(View):
   
    def dispatch(self, request, *args, **kwargs):
        return super(HomeView, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        return render(request, "home.html")

    def post(self, request):
        print("Home View POST method...")
        return redirect("/index/")

三盒件、分頁

當數(shù)據(jù)庫中數(shù)據(jù)有很多,我們通常會在前端頁面做分頁展示舱禽。
分頁的數(shù)據(jù)可以在前端頁面實現(xiàn)炒刁,也可以在后端實現(xiàn)分頁。
后端實現(xiàn)分頁的原理就是每次只請求一頁數(shù)據(jù)誊稚。
準備工作
我們使用腳本批量創(chuàng)建一些測試數(shù)據(jù)(將下面的代碼保存到bulk_create.py文件中放到Django項目的根目錄翔始,直接執(zhí)行即可罗心。):

import os

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "about_orm.settings")

    import django
    django.setup()

    from app01 import models
    bulk_obj = (models.Publisher(name='沙河第{}出版社'.format(i)) for i in range(300))
    models.Publisher.objects.bulk_create(bulk_obj)

1. 自定義分頁
無封裝,直接調(diào)用版本:

def publisher_list(request):
    # 從URL中取當前訪問的頁碼數(shù)
    try:
        current_page = int(request.GET.get('page'))
    except Exception as e:
        # 取不到或者頁碼數(shù)不是數(shù)字都默認展示第1頁
        current_page = 1
    # 總數(shù)據(jù)量
    total_count = models.Publisher.objects.count()
    # 定義每頁顯示多少條數(shù)據(jù)
    per_page = 10
    # 計算出總頁碼數(shù)
    total_page, more = divmod(total_count, per_page)
    if more:
        total_page += 1
    # 定義頁面上最多顯示多少頁碼(為了左右對稱城瞎,一般設(shè)為奇數(shù))
    max_show = 11
    half_show = max_show // 2
    # 計算一下頁面顯示的頁碼范圍
    if total_page <= max_show:  # 總頁碼數(shù)小于最大顯示頁碼數(shù)
        page_start = 1
        page_end = total_page
    elif current_page + half_show >= total_page:  # 右邊越界
        page_end = total_page
        page_start = total_page - max_show
    elif current_page - half_show <= 1:  # 左邊越界
        page_start = 1
        page_end = max_show
    else:  # 正常頁碼區(qū)間
        page_start = current_page - half_show
        page_end = current_page + half_show
    # 數(shù)據(jù)索引起始位置
    data_start = (current_page-1) * per_page
    data_end = current_page * per_page

    publisher_list = models.Publisher.objects.all()[data_start:data_end]

    # 生成頁面上顯示的頁碼
    page_html_list = []
    page_html_list.append('<nav aria-label="Page navigation"><ul class="pagination">')
    # 加首頁
    first_li = '<li><a href="/publisher_list/?page=1">首頁</a></li>'
    page_html_list.append(first_li)
    # 加上一頁
    if current_page == 1:
        prev_li = '<li><a href="#"><span aria-hidden="true">&laquo;</span></a></li>'
    else:
        prev_li = '<li><a href="/publisher_list/?page={}"><span aria-hidden="true">&laquo;</span></a></li>'.format(current_page - 1)
    page_html_list.append(prev_li)
    for i in range(page_start, page_end + 1):
        if i == current_page:
            li_tag = '<li class="active"><a href="/publisher_list/?page={0}">{0}</a></li>'.format(i)
        else:
            li_tag = '<li><a href="/publisher_list/?page={0}">{0}</a></li>'.format(i)
        page_html_list.append(li_tag)
    # 加下一頁
    if current_page == total_page:
        next_li = '<li><a href="#"><span aria-hidden="true">&raquo;</span></a></li>'
    else:
        next_li = '<li><a href="/publisher_list/?page={}"><span aria-hidden="true">&raquo;</span></a></li>'.format(current_page + 1)
    page_html_list.append(next_li)
    # 加尾頁
    page_end_li = '<li><a href="/publisher_list/?page={}">尾頁</a></li>'.format(total_page)
    page_html_list.append(page_end_li)
    page_html_list.append('</ul></nav>')
    page_html = "".join(page_html_list)
    return render(request, "publisher_list.html", {"publisher_list": publisher_list, "page_html": page_html})

封裝保存版:

class Pagination(object):
    """自定義分頁(Bootstrap版)"""
    def __init__(self, current_page, total_count, base_url, per_page=10, max_show=11):
        """
        :param current_page: 當前請求的頁碼
        :param total_count: 總數(shù)據(jù)量
        :param base_url: 請求的URL
        :param per_page: 每頁顯示的數(shù)據(jù)量渤闷,默認值為10
        :param max_show: 頁面上最多顯示多少個頁碼,默認值為11
        """
        try:
            self.current_page = int(current_page)
        except Exception as e:
            # 取不到或者頁碼數(shù)不是數(shù)字都默認展示第1頁
            self.current_page = 1
        # 定義每頁顯示多少條數(shù)據(jù)
        self.per_page = per_page
        # 計算出總頁碼數(shù)
        total_page, more = divmod(total_count, per_page)
        if more:
            total_page += 1
        self.total_page = total_page
        # 定義頁面上最多顯示多少頁碼(為了左右對稱脖镀,一般設(shè)為奇數(shù))
        self.max_show = max_show
        self.half_show = max_show // 2
        self.base_url = base_url

    @property
    def start(self):
        return (self.current_page-1) * self.per_page

    @property
    def end(self):
        return self.current_page * self.per_page

    def page_html(self):
        # 計算一下頁面顯示的頁碼范圍
        if self.total_page <= self.max_show:  # 總頁碼數(shù)小于最大顯示頁碼數(shù)
            page_start = 1
            page_end = self.total_page
        elif self.current_page + self.half_show >= self.total_page:  # 右邊越界
            page_end = self.total_page
            page_start = self.total_page - self.max_show
        elif self.current_page - self.half_show <= 1:  # 左邊越界
            page_start = 1
            page_end = self.max_show
        else:  # 正常頁碼區(qū)間
            page_start = self.current_page - self.half_show
            page_end = self.current_page + self.half_show
        # 生成頁面上顯示的頁碼
        page_html_list = []
        page_html_list.append('<nav aria-label="Page navigation"><ul class="pagination">')
        # 加首頁
        first_li = '<li><a href="{}?page=1">首頁</a></li>'.format(self.base_url)
        page_html_list.append(first_li)
        # 加上一頁
        if self.current_page == 1:
            prev_li = '<li><a href="#"><span aria-hidden="true">&laquo;</span></a></li>'
        else:
            prev_li = '<li><a href="{}?page={}"><span aria-hidden="true">&laquo;</span></a></li>'.format(
                self.base_url, self.current_page - 1)
        page_html_list.append(prev_li)
        for i in range(page_start, page_end + 1):
            if i == self.current_page:
                li_tag = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
            else:
                li_tag = '<li><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
            page_html_list.append(li_tag)
        # 加下一頁
        if self.current_page == self.total_page:
            next_li = '<li><a href="#"><span aria-hidden="true">&raquo;</span></a></li>'
        else:
            next_li = '<li><a href="{}?page={}"><span aria-hidden="true">&raquo;</span></a></li>'.format(
                self.base_url, self.current_page + 1)
        page_html_list.append(next_li)
        # 加尾頁
        page_end_li = '<li><a href="{}?page={}">尾頁</a></li>'.format(self.base_url, self.total_page)
        page_html_list.append(page_end_li)
        page_html_list.append('</ul></nav>')
        return "".join(page_html_list)

封裝保存版調(diào)用示例:

def publisher_list(request):
    # 從URL中取當前訪問的頁碼數(shù)
    current_page = int(request.GET.get('page'))
    # 比len(models.Publisher.objects.all())更高效
    total_count = models.Publisher.objects.count()
    page_obj = Pagination(current_page, total_count, request.path_info)
    data = models.Publisher.objects.all()[page_obj.start:page_obj.end]
    page_html = page_obj.page_html()
    return render(request, "publisher_list.html", {"publisher_list": data, "page_html": page_html})

封裝保存版html部分:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>書籍列表</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
</head>
<body>

<div class="container">
    <table class="table table-bordered">
      <thead>
        <tr>
            <th>序號</th>
            <th>id</th>
            <th>書名</th>
        </tr>
      </thead>
        <tbody>
        {% for book in books %}
            <tr>
            <td>{{ forloop.counter }}</td>
            <td>{{ book.id }}</td>
            <td>{{ book.title }}</td>
            </tr>
        {% endfor %}

        </tbody>
</table>
<nav aria-label="Page navigation">
  <ul class="pagination">
        {{ page_html|safe }}
  </ul>
</nav>
</div>
</body>
</html>

2. Django內(nèi)置分頁

view部分

from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

L = []
for i in range(999):
    L.append(i)

def index(request):
    current_page = request.GET.get('p')

    paginator = Paginator(L, 10)
    # per_page: 每頁顯示條目數(shù)量
    # count:    數(shù)據(jù)總個數(shù)
    # num_pages:總頁數(shù)
    # page_range:總頁數(shù)的索引范圍飒箭,如: (1,10),(1,200)
    # page:     page對象
    try:
        posts = paginator.page(current_page)
        # has_next              是否有下一頁
        # next_page_number      下一頁頁碼
        # has_previous          是否有上一頁
        # previous_page_number  上一頁頁碼
        # object_list           分頁之后的數(shù)據(jù)列表
        # number                當前頁
        # paginator             paginator對象
    except PageNotAnInteger:
        posts = paginator.page(1)
    except EmptyPage:
        posts = paginator.page(paginator.num_pages)
    return render(request, 'index.html', {'posts': posts})

html部分

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<ul>
    {% for item in posts %}
        <li>{{ item }}</li>
    {% endfor %}
</ul>

<div class="pagination">
      <span class="step-links">
        {% if posts.has_previous %}
            <a href="?p={{ posts.previous_page_number }}">Previous</a>
        {% endif %}
          <span class="current">
            Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
          </span>
          {% if posts.has_next %}
              <a href="?p={{ posts.next_page_number }}">Next</a>
          {% endif %}
      </span>

</div>
</body>
</html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蜒灰,隨后出現(xiàn)的幾起案子弦蹂,更是在濱河造成了極大的恐慌,老刑警劉巖卷员,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盈匾,死亡現(xiàn)場離奇詭異,居然都是意外死亡毕骡,警方通過查閱死者的電腦和手機削饵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來未巫,“玉大人窿撬,你說我怎么就攤上這事⌒鸱玻” “怎么了劈伴?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長握爷。 經(jīng)常有香客問我跛璧,道長,這世上最難降的妖魔是什么新啼? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任追城,我火速辦了婚禮,結(jié)果婚禮上燥撞,老公的妹妹穿的比我還像新娘座柱。我一直安慰自己,他們只是感情好物舒,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布色洞。 她就那樣靜靜地躺著,像睡著了一般冠胯。 火紅的嫁衣襯著肌膚如雪火诸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天涵叮,我揣著相機與錄音惭蹂,去河邊找鬼伞插。 笑死,一個胖子當著我的面吹牛盾碗,可吹牛的內(nèi)容都是我干的媚污。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼廷雅,長吁一口氣:“原來是場噩夢啊……” “哼耗美!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起航缀,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤商架,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后芥玉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蛇摸,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年灿巧,在試婚紗的時候發(fā)現(xiàn)自己被綠了赶袄。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡抠藕,死狀恐怖饿肺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情盾似,我是刑警寧澤敬辣,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站零院,受9級特大地震影響溉跃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜告抄,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一喊积、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧玄妈,春花似錦、人聲如沸髓梅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽枯饿。三九已至酝锅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間奢方,已是汗流浹背搔扁。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工爸舒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人稿蹲。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓扭勉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親苛聘。 傳聞我的和親對象是個殘疾皇子涂炎,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 利用HTTP協(xié)議向服務器傳參的幾種途徑、響應设哗、Cookie唱捣、Session、類視圖网梢、中間件 注意: 1>Dja...
    Cestine閱讀 1,245評論 0 2
  • Cookie Cookie的由來 大家都知道HTTp協(xié)議是無狀態(tài)的战虏。無狀態(tài)的意思是每次請求都是獨立的拣宰,它的執(zhí)行情況...
    可笑的黑耀斑閱讀 358評論 0 0
  • 模塊間聯(lián)系越多,其耦合性越強活烙,同時表明其獨立性越差( 降低耦合性徐裸,可以提高其獨立性)。軟件設(shè)計中通常用耦合度和內(nèi)聚...
    riverstation閱讀 2,064評論 0 8
  • 會話(Session)跟蹤是Web程序中常用的技術(shù)啸盏,用來跟蹤用戶的整個會話重贺。常用的會話跟蹤技術(shù)是Cookie與Se...
    chinariver閱讀 5,601評論 1 49
  • 前言 在android中,BLE的特征一次讀寫最大長度20字節(jié)回懦。對于長時間連續(xù)發(fā)送的大于20字節(jié)的幀結(jié)構(gòu)气笙,如果安卓...
    安迪豬閱讀 4,840評論 0 14