Flask Web DEvelopment 翻譯1

這幾天想學(xué)新東西,就看了flask框架,本身對python不太了解,網(wǎng)上的很多教程看了,總是在某些地方卡住。翻到一本電子書《Flask web Development》,還不錯。但是說實話,英語比較渣,原文看起來很累,并且由于偷懶總習(xí)慣只看代碼,而不看作者的解釋。這樣學(xué)習(xí)沒有效率,第一遍很快只看代碼就完成了,程序也能跑起來。但只圖快的后果就是幾乎沒啥收獲,很多東西都只知其然。
  為了避免偷懶,下決心每天翻譯一點,堅持仔細認(rèn)真學(xué)習(xí)。從第二章開始,第一張的安裝神馬的都跳過了。翻譯盡量卡著原字句走,只根據(jù)漢語習(xí)慣略作調(diào)整;有些專用語可能不準(zhǔn)確,另外盡量不看字典,只憑上下文猜不認(rèn)識的單詞——據(jù)說這也是背單詞手段之一:-)。所以必然會有錯誤之處,歡迎指正。

第二章 基本程序結(jié)構(gòu)

本章你將學(xué)到Flask程序的不同部分,你也將編寫并運行你的第一個Flask應(yīng)用。

初始化

所有的Flask程序必須創(chuàng)建一個"程序?qū)嵗?,Web服務(wù)器將自己接收到的所有客戶端請求轉(zhuǎn)發(fā)給這一對象,使用的是網(wǎng)頁服務(wù)網(wǎng)管接口協(xié)議(WSGI)。這一程序?qū)嵗且粋€Flask類的對象,通常通過如下代碼進行創(chuàng)建:

from flask import Flask
app = Flask(__name__)

Flask類初始化參數(shù)是程序的包或主模塊的名字。對大多數(shù)程序來說,Python的__name__變量就是正確的值。

注意:
傳遞給Flask程序構(gòu)造函數(shù)的name參數(shù)往往給新開發(fā)人員造成困擾。Flask采用這個參數(shù)判定程序的根目錄,以便于以后在程序中引用和查找相關(guān)資源。

稍后,你將看到更多完整的程序初始化的例子,單對一個簡單程序來說已經(jīng)足夠了。

路由和視圖函數(shù)

像瀏覽器這樣的客戶端發(fā)送請求(request)給服務(wù)器,服務(wù)器按順序轉(zhuǎn)發(fā)給Flask程序?qū)嵗?。程序?qū)嵗枰缹γ總€URL(統(tǒng)一資源定位符,也就是你在地址欄里看到的那一大長串)請求運行哪一部分的代碼,所以它保持著一個關(guān)于URL和Python函數(shù)的映射表。對URL和函數(shù)之間關(guān)聯(lián)進行控制的就稱之為路由(route)。
  定義路由的最方便的方法是通過app.route裝飾器暴露|裝飾一個函數(shù),程序?qū)嵗蜁堰@一函數(shù)注冊為一個路由。下列代碼展示了如何使用裝飾器來聲明一個路由:

@app.route('/')
def index():
    return '<h1>Hello World!</h1>`

注意:
  *裝飾器(Decorator)是python語言的標(biāo)準(zhǔn)功能,它可以在不同方式下更改一個函數(shù)的行為。最常見的就是使用裝飾器指定一個函數(shù)作為某事件的處理器 *

上述示例代碼將index()函數(shù)注冊為程序根URL的處理控制器。在程序部署到服務(wù)器上并關(guān)聯(lián)www.example.com域名后,在瀏覽器訪問www.example.com時,將觸發(fā)程序的index()函數(shù)。該函數(shù)的返回值——稱之為響應(yīng)(response),就是客戶端接收到的內(nèi)容。如果客戶端是瀏覽器,該響應(yīng)就是展示用網(wǎng)頁形式給用戶的文檔。
  像index()這樣的函數(shù)被稱為視圖函數(shù)(view functions)。視圖函數(shù)的返回響應(yīng)可以是簡單的html文本串,也可以是包含更復(fù)雜的表單——稍后可見。

注意:
響應(yīng)字符串嵌入在Python代碼中將導(dǎo)致代碼難以維護。這里只是簡單介紹響應(yīng)方式。你可以在第三章中學(xué)到如何正確生成響應(yīng)的方法。

如果注意下每天使用網(wǎng)絡(luò)服務(wù)的URL的形式,你可能會看到包含變量段。舉例來說:你的facebook個人信息頁面地址應(yīng)該是http://www.facebook.com/<yourname>,你的名字就是變量部分。Flask通過路由裝飾器的特殊語法來支持這一類型的URL。下面的例子定義了一個擁有變量名稱的路由:

@app.route('/user/<name>')
def user(name):
    return '<h1>Hello, %s!</h1>' % name

小括號部分就是動態(tài)部分,符合靜態(tài)部分的URL請求會被映射到這一路由。調(diào)用視圖函數(shù)時,F(xiàn)lask就會把動態(tài)部分作為一個參數(shù)發(fā)給它。在上面的視圖函數(shù)里,這一參數(shù)被用來生成個性化的歡迎信息并作為一個響應(yīng)返回。
  在路由中動態(tài)部分默認(rèn)是作為字符串處理,但也可以指定為某種類型。如:/user/<int:id>將只匹配包含整數(shù)的id動態(tài)參數(shù)URL。Flask路由支持int,float和path。path類型看起來也是一個字符串但其中的斜杠并不被認(rèn)為是分隔符,而是動態(tài)參數(shù)的一部分,不再對其進行解釋。

啟動服務(wù)

程序?qū)嵗衦un方法來運行Flask集成開發(fā)服務(wù)器:

if __name__ == '__main__':
    app.run(debug=True) 

__name__=='__main__'是python常見的方言,這里是用來保證僅僅在直接運行腳本的情況下啟動開發(fā)服務(wù)器。當(dāng)腳本被其他腳本導(dǎo)入時,它將假定調(diào)用它的父級腳本會運行另外的服務(wù)器,就跳過后面app.run()。
  一旦服務(wù)器啟動,它就進入循環(huán),等待請求并為之提供服務(wù)。該循環(huán)持續(xù)不斷直到程序結(jié)束,例如按下Ctrl+C。
  還有基本參數(shù)選項可以指定給app.run()來配置服務(wù)器操作模式。在開發(fā)模式下,服務(wù)器將啟動調(diào)試,這將激活debugger和reloader(調(diào)試模式和重載)。你只需設(shè)置參數(shù)為debug=True

注意:
Flask提供的web服務(wù)器"不可用于生產(chǎn)環(huán)境"。你將在第七章學(xué)習(xí)如何設(shè)置生產(chǎn)web服務(wù)器。

完整的程序

在上一節(jié),你已經(jīng)學(xué)習(xí)了Flask的不同部分,現(xiàn)在是時候自己寫一個了。完整的hello.py腳本程序僅僅就是將我們在前面描述過的三部分內(nèi)容合并到一個文件中,如下:

Example 2-1. hello.py: A complete Flask application
app = Flask(__name__)
@app.route('/')
def index():
    return '<h1>Hello World!</h1>'
if __name__ == '__main__':
    app.run(debug=True)`

要運行這個程序,你需要確保先前你設(shè)置的虛擬開發(fā)環(huán)境(第一章設(shè)置 安裝python 后 pip install virtualenv)已激活并且安裝了Flask?,F(xiàn)在打開你的web瀏覽器并在地址欄里輸入http://127.0.0.1:5000/ ,如果正常的話,瀏覽器將顯示服務(wù)器的響應(yīng)——頁面出現(xiàn)“Hello World!”。當(dāng)然,運行服務(wù)器的話需要在命令行中輸入如下命令:

(venv)$python hello.py
*running on http://127.0.0.1:5000
*Restarting with realoader`

如果你輸了其他的URL,該程序就不知道應(yīng)該如何處理,它將返回一個404錯誤代碼給瀏覽器——這意味著你要訪問的頁面并不存在。
  改進版本的程序如2-2示例所示,它添加了第二路由——包含動態(tài)參數(shù)。當(dāng)你訪問該URL時,將見到個性化的歡迎。

Example 2-2. hello.py: Flask application with a dynamic route
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
    return '<h1>Hello World!</h1>'
@app.route('/user/<name>')
def user(name):
    return '<h1>Hello, %s!</h1>' % name
if __name__ == '__main__':
    app.run(debug=True)`

要測試該動態(tài)路由,啟動服務(wù)器后訪問http://localhost:5000/user/Dave ,程序?qū)⒁詡€性化的歡迎來響應(yīng),根據(jù)動態(tài)參數(shù)name生成歡迎信息。每當(dāng)嘗試不同的名字,你會看到根據(jù)名字生成歡迎頁面。

譯注:2016-7-20,現(xiàn)在全新安裝虛擬環(huán)境的話,F(xiàn)lask已經(jīng)升級到0.11.1了,會出現(xiàn)一些提醒信息,比如導(dǎo)入擴展的語法將要從form flask.ext.moment import Moment變更為from flask_moment import Moment。當(dāng)然,這并不意味著是錯誤,程序仍舊可以照常運行的。這是為將來大版本語法變動的預(yù)防針:-)

請求-響應(yīng)循環(huán)

現(xiàn)在你已經(jīng)搞定一個基本的Flask程序了,你可能希望對Flask工作過程了解的更多。下面的小節(jié)描述了一些框架的設(shè)計模樣(?)。

應(yīng)用程序和請求上下文

當(dāng)Falsk接收到客戶端的請求,他需要激活一些視圖函數(shù)需要的對象來處理它們。最好的例子就是request對象,它封裝了所有的客戶端http請求。
  最簡單的作法是將它作為一個參數(shù)發(fā)送,這樣Flask就能讓一個視圖函數(shù)訪問“請求對象”,但這也會導(dǎo)致每個單一視圖函數(shù)都要有可擴展的參數(shù):視圖函數(shù)要完成一個請求訪問,可能需要訪問不僅是請求對象自己。考慮到這些,情況就更復(fù)雜了。
  為了避免雜亂的視圖函數(shù)帶著不一定需要的大量參數(shù),F(xiàn)lask使用上下文(contexts),來暫時為特定對象提供被全局訪問的可能。多虧了上下文,視圖函數(shù)就可以如下書寫:

from flask import request
@app.route('/')
def index():
user_agent = request.headers.get('User-Agent')
return '<p>Your browser is %s</p>' % user_agent

注意,在這個視圖函數(shù)中request就像一個全局變量一樣被使用。實際上,你仔細考慮下就會發(fā)現(xiàn),request不可能是一個全局變量——在一個多線程服務(wù)器上,在同一時間線程工作在不同客戶端請求上,所以每個線程需要看到不同的——自己特定的那個request對象。上下文就使Flask的這一功能實現(xiàn),某一特定變量只對一個線程可見而其他的則看不到。

注意:
線程 是可以獨立管理的最小指令序列。通常,一個進程(process)擁有多個活動的線程,他們可以共享資源如內(nèi)存或文件句柄。多線程web服務(wù)器會啟動一個線程池,每當(dāng)進來一個請求就從線程池里調(diào)起一個線程來進行處理。

在Flask中有兩個上下文:程序上下文請求上下文。下表展示了每個上下文擁有的變量。

*變量名*         *上下文*      *描述*               
current_app     程序上下文     當(dāng)前活動的程序?qū)嵗?       
g               程序上下文     對象程序可以請求發(fā)起是用來臨時存儲數(shù)據(jù),每個請求發(fā)起都會重置。
request         請求上下文     請求對象本身,封裝了客戶端發(fā)來的http請求內(nèi)容  
session         請求上下文     用戶會話,一個字典,程序可以用來在各個請求之間記住存儲的值。

在分發(fā)請求或處理后移除請求前,flask激活(或推出)程序上下文和請求上下文。當(dāng)程序上下文被推出,current_app和g 變量對線程來說就生效了,同樣,當(dāng)請求上下文被推出,request和session也將生效。如果激活沒有活動程序或請求上下文就訪問這些變量,將導(dǎo)致報錯。如果你還不太理解他們?yōu)楹芜@么有用,不需要擔(dān)心,后面我們將詳細了解
  下列python shell會話模擬展示了程序上下文是如何工作的:

>>> from hello import app
>>> from flask import current_app
>>> current_app.name
Traceback (most recent call last):
...
RuntimeError: working outside of application context
>>> app_ctx = app.app_context()
>>> app_ctx.push()
>>> current_app.name
'hello'
>>> app_ctx.pop()

在這里,如果沒有程序激活則current_app.name失敗了,相反上下文被推出則有效。注意,在程序?qū)嵗鲜侨绾瓮ㄟ^app.app_context()來調(diào)用程序上下文的。

請求分發(fā)

當(dāng)程序接收到客戶端請求時,它需要查找視圖函數(shù)來為之服務(wù)。在這任務(wù)里,F(xiàn)lask在URL映射中(包含著URL和對應(yīng)視圖函數(shù)的映射)查找請求的URL來處理之。Flask通過app.route裝飾器(或等價的非裝飾器版本:app.add_url_rule()函數(shù))來創(chuàng)建這一映射。
  Url映射是啥樣的呢,你可以檢查在python shell 中hello.py創(chuàng)建的這個映射。首先確保你的虛擬安裝環(huán)境激活:

 (venv) $ python
>>> from hello import app
>>> app.url_map
Map([<Rule '/' (HEAD, OPTIONS, GET) -> index>,
<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
<Rule '/user/<name>' (HEAD, OPTIONS, GET) -> user>])

‘/’和/user/<name>路由是在程序中通過app.route裝飾器定義的。/static/<filename>路由則是Flask添加用來訪問靜態(tài)文件的。你將在第三張學(xué)到更多的關(guān)于靜態(tài)文件的東西。
  在URL映射中出現(xiàn)的HEAD,OPTIONS,GET元素是路由控制處理的“請求方法”。Flask給每個路由附加上方法,這樣不同的請求方法就會被發(fā)送到同一URL但被不同的視圖函數(shù)處理。HEAD和OPTIONS方法由Flask自動管理,所以實際上也可以說本程序的三個路由在URL映射中添加了GET方法。
  在第四章你將學(xué)習(xí)路由不同請求之間的差異。

請求鉤子

有些時候,需要在請求被執(zhí)行之前或之后執(zhí)行某些代碼,鉤子就派上了用場。舉例來說,在每個請求的開始部分,可能需要創(chuàng)建一個數(shù)據(jù)庫連接,或者許可用戶執(zhí)行該請求。Flask提供了選項來注冊一個通用函數(shù),以便于在一個請求被分派到視圖函數(shù)之前或之后來調(diào)用,這可以避免在每個視圖函數(shù)中重復(fù)復(fù)制代碼來實現(xiàn)其功能。
  請求鉤子以裝飾器的形式來實現(xiàn)。Flask支持四種鉤子:

before_first_request: 在處理第一個請求之前執(zhí)行該注冊函數(shù)
before_request:       在每個請求前都執(zhí)行該注冊函數(shù)
after_request:        在每個請求之后都執(zhí)行該注冊函數(shù),如果沒有未被處理的錯誤的話。
teardown_request:     在每個請求之后都執(zhí)行該注冊函數(shù),即使有未被處理的錯誤

為了在請求鉤子和視圖函數(shù)之間共享數(shù)據(jù),一個常用方案就是使用全局上下文g。舉例來說,before_request句柄能從數(shù)據(jù)庫中加載已登錄的用戶,并將之存儲在g.user對象。然后,如果調(diào)用視圖函數(shù),他就可以從這訪問用戶信息。
  在下面章節(jié)中將展示請求鉤子,所以即使現(xiàn)在沒有啥感覺也不需擔(dān)心。

響應(yīng)

當(dāng)Flask調(diào)用視圖函數(shù),它期待該函數(shù)將返回值作為對請求的回應(yīng)。在大部分情況下,響應(yīng)是一個簡單的字符串被發(fā)送給客戶端呈現(xiàn)為HTML頁面。
  但HTTP協(xié)議要求不僅僅是字符串作為響應(yīng)。HTTP響應(yīng)一個非常重要的部分就是響應(yīng)狀態(tài)代碼,flask通常默認(rèn)設(shè)置為“200”,它代表請求被成功回復(fù)。
  當(dāng)視圖函數(shù)需要用不同的狀態(tài)代碼回復(fù)響應(yīng)時,它就會把一個數(shù)值添加在相應(yīng)文本后,作為第二個返回值。舉例來說,下列視圖函數(shù)將返回狀態(tài)碼400,它意味著請求錯誤:

@app.route('/')
def index():
    return '<h1>Bad Request</h1>', 400

視圖函數(shù)返回的響應(yīng)也可以攜帶第三個參數(shù)——添加在一個http響應(yīng)上的字典頭部。這是比較少見的,但你將在第14章看到示例。
  作為返回一個、兩個、甚至三個值的元組的替代方案,F(xiàn)lask視圖函數(shù)還可以選擇返回一個對象(response對象)。make_response()函數(shù)可以取1、2或3個參數(shù),這些值被作為視圖函數(shù)的響應(yīng)統(tǒng)一作為一個對象response返回。有時候,這很有用,他可以在視圖函數(shù)內(nèi)部進行轉(zhuǎn)換然后使用響應(yīng)對象的方法深度配置響應(yīng)。下面是一個創(chuàng)建響應(yīng)對象并在其中設(shè)置cookie的例子:

from flask import make_response
@app.route('/')
def index():
    response = make_response('<h1>This document carries a cookie!</h1>')
    response.set_cookie('answer', '42')
    return response

這里出現(xiàn)了一個特殊響應(yīng)類型叫redirect。這個響應(yīng)并不包含頁面文檔,它只是給瀏覽器一個新的URL地址以供瀏覽器加載新頁面。在第四章你將學(xué)到重定向通常和web表單同用。
  一個重定向通常以302響應(yīng)代碼加上location頭部的URL地址來聲明。重定向響應(yīng)可以使用三個返回值或者一個response對象來生成,但為了便于使用,F(xiàn)lask提供了redirect()函數(shù)住手來創(chuàng)建。

from flask import redirect
@app.route('/')
def index():
    return redirect('http://www.example.com')

其他的特殊響應(yīng)是abort函數(shù),他被用來處理錯誤。下面的代碼展示了當(dāng)傳遞給URL的id參數(shù)沒有匹配的用戶是返回一個404狀態(tài)碼:

from flask import abort
@app.route('/user/<id>')
def get_user(id):
    user = load_user(id)
    if not user:
        abort(404)
    return '<h1>Hello, %s</h1>' % user.name

注意:abort并不是將控制交還給調(diào)用它的函數(shù),而是以跳出一個錯誤的方式將控制轉(zhuǎn)交給了web服務(wù)器。

Flask擴展

Flask本身被設(shè)計成可擴展的。他特意空出一些重要部分,諸如數(shù)據(jù)庫,用戶認(rèn)證,這樣便于你自由選擇最適合那你程序的包或者自行編寫。
  社區(qū)創(chuàng)建了針對各種要求的多種擴展,如果不夠還是有任意的標(biāo)準(zhǔn)python包或庫可供選擇使用。為了展示如何在程序中使用擴展,下面小節(jié)在你hello.py中添加了一個擴展以使程序能夠處理命令行參數(shù)。

通過Flask-script實現(xiàn)命令行選項

Flask的開發(fā)服務(wù)器支持啟動配置項,但唯一的方法就是在教程中給app.run()傳遞指定的參數(shù)。這非常不便,理想方法是公共命令行參數(shù)傳遞配置項。
  Flask-Script就是這樣一個給你的Flask程序添加命令行參數(shù)的擴展。他支持通常選項配置也支持自定義命令。
  這個擴展可以通過pip安裝:
(venv)$pip install flask-script
2-3例子展示了在hello.py中添加命令行解釋器所需要進行的改動。

example2-3: hello.py:使用Flask-script
from flask.ext.script import Manager
manager = Manager(app)
# ...
if __name__ == '__main__':
    manager.run() 

擴展是Flask特殊種類在flask.exe命名空間下暴露。Flask-script輸出一個名為Manager的類,可以從flask.ext.script中導(dǎo)入。
  這個擴展的初始化方法和其他擴展類似:就愛能夠應(yīng)用程序示例作為參數(shù)傳遞給它的構(gòu)造函數(shù),從而生成一個類實例。該對象可以隨后被其他擴展使用。在本例中,通過manager.run()路由進行服務(wù)器啟動,同樣可以由此分析解釋命令行。
  通過這些修改,程序要求一個基本的命令行選項配置參數(shù)?,F(xiàn)在運行一下hello.py看看其可用的信息:

$ python hello.py
usage: hello.py [-h] {shell,runserver} ...
positional arguments:
{shell,runserver}
    shell Runs a Python shell inside Flask application context.
    runserver Runs the Flask development server i.e. app.run()
optional arguments:
    -h, --help show this help message and exit`

shell命令可以用來在程序上下文中啟動一個python shell 會話。你可以使用這個會話進行維護任務(wù)或者測試,調(diào)試問題。
  runserver命令,就像其字面意思一樣,將啟動服務(wù)器:運行python hello.py runserver將 以調(diào)試模式啟動服務(wù)器,同樣,這里還有更多地可以選項:

(venv) $ python hello.py runserver --help
usage: hello.py runserver [-h] [-t HOST] [-p PORT] [--threaded]
                                [--processes PROCESSES] [--passthrough-errors] [-d]
                                [-r]
Runs the Flask development server i.e. app.run()

optional arguments:
-h, --help show this help message and exit
-t HOST, --host HOST
-p PORT, --port PORT
--threaded
--processes PROCESSES
--passthrough-errors
-d, --no-debug
-r, --no-reload`

--host 參數(shù) 非常有用,他告訴服務(wù)器監(jiān)聽哪個網(wǎng)絡(luò)接口來連接客戶端。默認(rèn)情況,F(xiàn)lask開發(fā)服務(wù)器監(jiān)聽localhost的連接,這時候只有來自于本機內(nèi)部的連接才會被接受。下列命令指定服務(wù)器鑒定在公用網(wǎng)絡(luò)接口上的連接,允許網(wǎng)絡(luò)中的其他計算機連接上來:

(venv) $ python hello.py runserver --host 0.0.0.0
* Running on http://0.0.0.0:5000/
* Restarting with reloader

web服務(wù)器現(xiàn)在允許網(wǎng)絡(luò)中的任意計算機訪問http://a.b.c.d:5000 , a.b.c.d是運行服務(wù)器計算機的擴展ip地址。
  本章介紹了請求應(yīng)答得概念,但關(guān)于應(yīng)答內(nèi)容很多并沒有細談。Flask根據(jù)模板對生成相應(yīng)提供了很好的支持,他們非常重要我們將在后續(xù)章節(jié)中詳解。
第三章 模板

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,958評論 2 373

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