離線應(yīng)用與客戶端存儲(23)

-進(jìn)行離線檢測
-使用離線緩存
-在瀏覽器中保存數(shù)據(jù)

離線web應(yīng)用我注,就是設(shè)備在不能上網(wǎng)的情況下仍然可以運(yùn)行的應(yīng)用媳危。

離線檢測

navigator.onLine
這個(gè)屬性的關(guān)鍵是瀏覽器必須知道設(shè)備能否訪問網(wǎng)絡(luò)
true ==> 表示設(shè)備能上網(wǎng)
false ==> 表示設(shè)備離線

IE6和Safari 5+ 能夠正確檢測到網(wǎng)絡(luò)已經(jīng)斷開...略有兼容問題化借。但手機(jī)端的話蹬音,還ok

        if(navigator.onLine){
            console.log('能夠連接到網(wǎng)絡(luò)')
        }else{
            console.log('斷網(wǎng)啦')
        }

online,offline

        var EventUtil = {

            addHandler: function (element, type, handler) {
                if (element.addEventListener) {        //DOM2級
                    element.addEventListener(type, handler, false);

                } else if (element.attachEvent) {      //DOM1級
                    element.attachEvent("on" + type, handler);

                } else {
                    element["on" + type] = handler;    //DOM0級
                }
            },
        }
        
        EventUtil.addHandler(window,'online',function(){
            alert('online')
        })

        EventUtil.addHandler(window,'offline',function(){
            alert('offline')
        })

當(dāng)關(guān)閉網(wǎng)絡(luò)或開啟網(wǎng)絡(luò)時(shí)可以得到校驗(yàn)結(jié)果

navigator.onLine + online,offline
在頁面加載后,最好先通過navigator.onLine取得初始的狀態(tài)米绕。再通過online,offline來確定狀態(tài)是否變化垢村。


應(yīng)用緩存

appcache
Appcache是專門從瀏覽器的緩存中跟出來的一塊緩存區(qū)割疾,使用描述文件manifest file

<html manifest="offline.appcache">

描述文件的擴(kuò)展名以前推薦用manifest.現(xiàn)在推薦用appcache

CACHE MANIFEST
#Comment
index.js //描述文件中列出的都是需要下載的資源,已備離線時(shí)使用

applicationCache
雖然應(yīng)用緩存的意思是確保離線時(shí)資源可用肝断,但也有相應(yīng)的JavaScript API 讓你知道它在作什么
狀態(tài)

  • 0
    無緩存
  • 1
    閑置杈曲。未更新
  • 2
    檢查中。正在下載描述文件并檢查更新
  • 3
    下載中胸懈,即應(yīng)用混存正在下載描述文件
  • 4
    更新完成蛉腌∑旯可以通過swapCache()來使用
  • 5
    廢棄晾浴。即應(yīng)用已經(jīng)不存在
    事件
  • checking
    在瀏覽器為應(yīng)用緩存查找更新時(shí)觸發(fā)
  • error
    在檢查更新或下載資源期間發(fā)生錯(cuò)誤時(shí)觸發(fā)
  • noupdate
    在檢查描述文件發(fā)現(xiàn)文件無變化時(shí)觸發(fā)
  • downloading
    在開始下載應(yīng)用緩存資源時(shí)觸發(fā)
  • progress
    在文件下載應(yīng)用緩存的過程中持續(xù)不斷的觸發(fā)
  • updateready
    在頁面新的應(yīng)用緩存下載完畢且可以通過swapCache()使用時(shí)觸發(fā)
  • cached
    在應(yīng)用緩存完整可用時(shí)觸發(fā)

數(shù)據(jù)存儲

Cookie
最初是在客戶端用于存儲會話信息的星岗,服務(wù)器對任意HTTP請求發(fā)送Set-Cookie頭部,發(fā)送回服務(wù)器的額外信息可以用于唯一驗(yàn)證客戶來自于發(fā)送的那個(gè)請求首有。

  1. 限制
    cookie在性質(zhì)上是綁定在特定的域名下的(瀏覽器限制)燕垃,每個(gè)域的cookie總數(shù)是有限的枢劝,當(dāng)超過數(shù)量時(shí),瀏覽器會清除以前設(shè)置的cookie卜壕,且會影響傳輸速度
  2. cookie的構(gòu)成
    名稱:不區(qū)分大小寫
    :存儲在cookie中的字符串值您旁,值必須被URL編碼
    :cookie對于哪個(gè)域是有效的。所有向該域發(fā)送的請求都會包含這個(gè)cookie信息轴捎。這個(gè)只可以包含子域鹤盒,也可以不包含
    路徑:對于指定域中的路徑,應(yīng)該向服務(wù)器發(fā)送cookie侦副,例如:
    http://www.xxxx.com/demo/中才能訪問侦锯,那么http://www.xxxx.com的頁面就不會發(fā)送cookie信息,即使請求都是來自同一個(gè)域的秦驯。
    失效時(shí)間:是GMT格式的日期尺碰,用于指定應(yīng)該刪除的準(zhǔn)確時(shí)間
    安全標(biāo)志:指定后cookie只有在使用SSL連接的時(shí)候才發(fā)動到服務(wù)器。
HTTP/1.1 200 OK 
Content-type: text/html 
Set-Cookie: name=value; 
domain=.wrox.com; path=/; secure 
Other-header: other-header-value
//以上表示一個(gè)叫做name的cookie译隘,
//在格林威治2007年1月22日7:10:24失效亲桥,
//同時(shí)對于www.wrow.com和wrow.com的任何子域(如:p2p.wrow.com)都有效
//secure 是cookie中唯一一個(gè)非名值對的部分,直接包含一個(gè)secure單詞固耘。

域两曼、路徑、失效時(shí)間玻驻、和secure標(biāo)志都是讀武器給瀏覽器的知識,以指定何時(shí)應(yīng)該發(fā)送cookie偿枕,這些參數(shù)并不會作為發(fā)送到服務(wù)器的cookie信息的一部分璧瞬,只有名值對才會被發(fā)送

3.JavaScript的cookie

name1=value1;name2=value2;name3=value3

所有名字和值都是經(jīng)過URL編碼的,所以必須使用decodeURIComponent()來解碼
4.子cookie
為了繞開瀏覽器的但域名下的cookie數(shù)限制渐夸,一些開發(fā)人員使用了一種稱為子cookie嗤锉。例如:

name=name1=value1&name2=value2&name3=value3=name4&value4&name5=value5

這昂網(wǎng)站或者web應(yīng)用可以無需達(dá)到單域名cookie上限也可以存儲更加結(jié)構(gòu)化的數(shù)據(jù)。
5.關(guān)于cookie的思考

還有一類cookie被稱為“HTTP專有cookie”墓塌,HTTP專有cookie可以從瀏覽器或者服務(wù)器設(shè)置瘟忱,但是只能從服務(wù)端讀取,因?yàn)镴avaScript無法獲取HTTP專有的cookie值

不要在cookie中存儲敏感信息苫幢,因?yàn)槎伎梢员辉L問到

cookie信息越大访诱。完成對服務(wù)的請求時(shí)間也就越長。


Web存儲機(jī)制

Web Storage

  • 提供一種在cookie之外存儲會話數(shù)據(jù)的途徑
  • 提供一種存儲大量可以跨會話存在的數(shù)據(jù)的機(jī)制
  1. Storage類型

Storage類型提供最大的存儲空間韩肝,storage的實(shí)例于其他對象類似

clear():刪除所有值触菜,F(xiàn)irefox中沒有實(shí)現(xiàn),只能清除值哀峻,不建議使用這個(gè)方法涡相。
getItem(name): 根據(jù)指定的名字name獲取對應(yīng)的值
key(index):獲得index位置處的值的名字
removeItem(name):刪除由name指定的名值對
setItem(name,value):為指定的name設(shè)置一個(gè)對應(yīng)的值

Storage類型只能存儲字符串哲泊,非字符串的數(shù)據(jù)在存儲之前會被轉(zhuǎn)換成字符串


2.sessionStorage對象
sessionStorage對象存儲特定于某個(gè)會話的數(shù)據(jù),也就是該數(shù)據(jù)值保持到瀏覽器關(guān)閉催蝗。這個(gè)對象就像會話cookie切威,也會在瀏覽器關(guān)閉后消失,刷新仍然保留丙号。
3.globalStorage對象(已被localStorage取代)
4.localStorage對象
不能給localStorage指定任何訪問規(guī)則先朦,頁面必須來自同一個(gè)域名(子域名無效)使用同一種協(xié)議。
5.限制
localStorage:大多數(shù)是5MB槽袄,Chrome和Safari限制是2.5MB
sessionStorage:大多數(shù)是5MB烙无,Chrome和Safari限制是2.5MB


IndexedDB

Indexed Database API,或者簡稱為IndexedDB遍尺,是在瀏覽器中保存結(jié)構(gòu)化數(shù)據(jù)的一種數(shù)據(jù)庫截酷。
IndexedDB的思想是創(chuàng)建一套API,方便保存和讀取JavaScript對象乾戏,同時(shí)還支持查詢及搜索迂苛。
我們使用時(shí)還是應(yīng)該要注意瀏覽器的兼容

var indexedDB = window.indexedDB ||
window.msIndexedDB ||
window.mozIndexedDB ||
window.webkitIndexedBD;

數(shù)據(jù)庫
IndexedDB就是一個(gè)數(shù)據(jù)庫,可以被網(wǎng)頁腳本創(chuàng)建和操作鼓择,IndexDB允許存儲大量數(shù)據(jù)三幻,提供查找接口,還能建立索引呐能,與MySQL或Web SQL Database等這些你以前可能用過的數(shù)據(jù)庫類似念搬。IndexedDB最大的特色是使用對象保存數(shù)據(jù),而不是用表來保存摆出。(IndexDB不屬于關(guān)系型數(shù)據(jù)庫朗徊,不支持SQL查詢)
特性
1.鍵值對存儲
IndexDB內(nèi)部采用對象倉庫(object store)存放數(shù)據(jù),所有類型的數(shù)據(jù)都可以直接存入偎漫,包括JavaScript對象爷恳,數(shù)據(jù)以“鍵值對”形式保存,每一額數(shù)據(jù)記錄都有對應(yīng)的主鍵象踊,主鍵獨(dú)一無二温亲,重復(fù)會報(bào)錯(cuò)。
2.異步
IndexedDB操作時(shí)不會鎖死瀏覽器杯矩,用戶依然可以進(jìn)行其他操作(LocalStorage是同步操作)
3.支持事務(wù)
IndexedDB支持事務(wù)(transaction 游標(biāo))栈虚,這意味著一系列操作步驟中,只要有一步失敗史隆,整個(gè)事務(wù)就都取消节芥,數(shù)據(jù)庫回滾到事務(wù)發(fā)生之前的狀態(tài),不存在只改寫一部分?jǐn)?shù)據(jù)的情況。
4.同源限制
IndexDB受到同源限制头镊,每一個(gè)數(shù)據(jù)庫對象創(chuàng)建它的域名蚣驼,網(wǎng)頁只能訪問自身域名下的數(shù)據(jù)庫,而不能訪問跨域的數(shù)據(jù)庫相艇。
5.存儲空間大
一般不少于250MB,甚至沒有上限
6.支持二進(jìn)制存儲
不僅可以存儲字符串颖杏,還可以存儲二進(jìn)制數(shù)據(jù)(ArrayBuffer對象和Blob對象)


操作

  1. 打開數(shù)據(jù)庫
    indexDB.open()
    如果存在則打開,如果不存在就創(chuàng)建一個(gè)并打開
    調(diào)用indexDB.open()會返回一個(gè)IDBRequest對象坛芽,這個(gè)對象上可以添加onerror和onsuccess事件處理程序
        var request, database
        request = indexedDB.open('demo'); // window.indexedDB.open(databaseName,version)
        request.onerror = function(event){
            console.log('Something bad happened',event)
        }
        request.onsuccess = function (event){
            console.log(event)
        }
        request.onupgradeneeded = function (event) {
             console.log(event)
        } //upgradeneeded事件留储,如果指定版本號大于數(shù)據(jù)庫的實(shí)際版本號,會發(fā)生數(shù)據(jù)庫升級事件

方法接受2個(gè)參數(shù)咙轩,第一個(gè)參數(shù)是數(shù)據(jù)庫的名字获讳,如果不存在新建,第二個(gè)參數(shù)是整數(shù)活喊,表示版本丐膝,如果省略,打開已有的數(shù)據(jù)庫時(shí)钾菊,默認(rèn)為當(dāng)前版本帅矗,新建數(shù)據(jù)庫時(shí),默認(rèn)為1

錯(cuò)誤碼
IDBDatabaseException.UNKNOWN_ERR(1):意外錯(cuò)誤煞烫,無法歸類浑此。
IDBDatabaseException.NON_TRANSIENT_ERR(2):操作不合法。
IDBDatabaseException_NOT_FOUND_ERR(3):未發(fā)現(xiàn)要操作的數(shù)據(jù)庫滞详。
IDBDatabaseException.CONSTRAINT_ERR(4):違反了數(shù)據(jù)庫約束凛俱。
IDBDatabaseException.DATA_ERR(5):提供給事務(wù)的數(shù)據(jù)不能滿足要求。
IDBDatabaseException.NOT_ALLOWED_ERR(6):操作不合法料饥。
IDBDatabaseException.TRANSACTION_INACTIVE_ERR(7):試圖重用已完成的事務(wù)最冰。
IDBDatabaseException.ABORT_ERR(8):請求中斷,未成功稀火。
IDBDatabaseException.READ_ONLY_ERR(9):試圖在只讀模式下寫入或修改數(shù)據(jù)。
IDBDatabaseException.TIMEOUT_ERR(10):在有效時(shí)間內(nèi)未完成操作赌朋。
IDBDatabaseException.QUOTA_ERR(11):磁盤空間不足凰狞。

默認(rèn)情況下,IndexedDB數(shù)據(jù)庫是沒有版本號的沛慢,最好一開始就為數(shù)據(jù)庫指定一個(gè)版本號赡若。為此可以調(diào)用setVersion()方法,傳入以字符串形式表示的版本號团甲。同樣逾冬,調(diào)用這個(gè)方法也會返回一個(gè)請求對象。

        function openIndexedDB(){
            return new Promise(
                (resolve,reject) => {
                    var request;
                    request = indexedDB.open('demo');
                    request.onerror = function(event){
                        reject(event.target.errorCode)
                    }
                    request.onsuccess = function (event){
                        resolve(event.target.result)
                    }
                }
            )
        }
        openIndexedDB().then(
            (res) => {
                console.log('IndexedDB',res)
            }
        )
  1. 對象存儲空間
    在建立了與數(shù)據(jù)庫的連接之后,下一步就是使用對象存儲空間身腻,如果數(shù)據(jù)庫的版本與你傳入的版本不匹配产还,需要?jiǎng)?chuàng)建一個(gè)新的對象存儲空間,在創(chuàng)建存儲空間之前嘀趟,必須要想清楚你想要什么數(shù)據(jù)類型脐区。
var user = {
  username: '007',
  firstName:'James',
  lastName:'Bond',
  password: 'foo',
}

在這里貼一篇詳細(xì)的IndexDB的文章
https://wangdoc.com/javascript/bom/indexeddb.html#indexeddb-%E5%AF%B9%E8%B1%A1
3.新建數(shù)據(jù)庫
新建數(shù)據(jù)庫與打開數(shù)據(jù)庫是同一個(gè)操作,不存在就新建她按,不同的在于牛隅,后續(xù)的操作主要在upgradeneeded事件的監(jiān)聽函數(shù)完成,因?yàn)榘姹緩臒o到有酌泰,就是觸發(fā)媒佣。

  • 新建倉庫(同MySql里的新建表)
request.onupgradeneeded = function (event){
    db = event.target.result;
    var objectStore = db.createObjectStore('person',{ keyPath: 'id' });
}
  • 新增表
    數(shù)據(jù)庫新建成功后,新增一張叫做 person 的表格陵刹,主鍵是 id
    更好的寫法是先判斷一下默伍,這張表格是否存在,不存在再新建
         var db = null;
         var request = window.indexedDB.open('demo')
         request.onerror = function (event) {
             db = request.result
             console.log( '數(shù)據(jù)庫打開報(bào)錯(cuò)' )
         }
         request.onsuccess = function (event) {
             db = request.result
             console.log( '數(shù)據(jù)庫打開成功' )
         }
         request.onupgradeneeded = function (event) {
             db = event.target.result
             var objectStore ;
             if(!db.objectStoreNames.contains('person')){
                 objectStore = db.createObjectStore('person', {keyPath: 'id'})
             }
             console.log('創(chuàng)建了倉庫',objectStore);
         }

主鍵(keyPath)是默認(rèn)建立索引的屬性授霸,比如:數(shù)據(jù)記錄是{ id: 1, name: '張三' }巡验,那么id屬性可以作為主鍵。主鍵也可以指定為下一層對象的屬性碘耳,比如:{ foo, { bar: 'baz' } }的foo.bar也可以指定為主鍵显设。

如果 數(shù)據(jù)記錄里面沒有合適作為主鍵的屬性,那么可以讓IndexedDB自動生成主鍵

var objectStore = db.createObjectStore(
  'person',
  { autoIncrement: true }
);
//指定主鍵為一個(gè)遞增的整數(shù)
  • 新建索引
    新建倉庫后辛辨,下一步可以新建索引
request.onupgradeneeded = function (event) {
    db = event.target.result
    var objectStore ;
    if(!db.objectStoreNames.contains('person')){
        objectStore = db.createObjectStore('person', {autoIncrement: true})
        objectStore.createIndex( 'name', 'name', {unique: false} )
        objectStore.createIndex( 'email', 'email', {unique: true} )
        //createIndex的三個(gè)參數(shù)分別為索引名稱捕捂、索引所在的屬性、配置對象(說明該屬性是否包含重復(fù)的值)
    }
    console.log('創(chuàng)建了倉庫',objectStore);
}

事務(wù)
接下來的一系列我們都叫做事務(wù)斗搞。
在數(shù)據(jù)庫對象上調(diào)用transaction()方法可以創(chuàng)建事務(wù)指攒,任何時(shí)候,只要想讀取或修改數(shù)據(jù)僻焚,都要通過事務(wù)來組織所有操作允悦。

var transaction = db.transaction(name);
//name為需要傳入的參數(shù)
var transaction = db.transaction(['name','email']);
//如果需要訪問多個(gè)對象存儲空間,也可以在第一個(gè)參數(shù)的位置傳字符串?dāng)?shù)組

以上都是以只讀方式訪問數(shù)據(jù)虑啤,要修改訪問方式隙弛,必須在創(chuàng)建事務(wù)時(shí)傳入第二個(gè)參數(shù),這個(gè)參數(shù)表示訪問模式
READ_ONLY:只讀
READ_WRITE:讀寫
VERSION_CHANGE:改變

IE10+和Firefox 4+實(shí)現(xiàn)的是IDBTransaction狞山,但在Chrome中則叫webkitIDBTransaction全闷,使用以下代碼可以統(tǒng)一:

var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction

var transaction = db.transaction('users',IDBTransaction.READ_WRITE)
  • 新增數(shù)據(jù)
    新增數(shù)據(jù)指的是向?qū)ο髠}庫寫入數(shù)據(jù)記錄。通過事務(wù)完成
function createStore (){
    return new Promise(
        (resolve,reject) => {
            var db = null;
            var request = window.indexedDB.open('demo')
            request.onerror = function (event) {
                db = request.result
                console.log( '數(shù)據(jù)庫打開報(bào)錯(cuò)',db )
                reject (db)
            }
            request.onsuccess = function (event) {
                db = request.result
                console.log( '數(shù)據(jù)庫打開成功',db )
                resolve(db)
            }
            request.onupgradeneeded = function (event) {
                db = event.target.result
                var objectStore;
                if (!db.objectStoreNames.contains('person')) {
                    objectStore = db.createObjectStore('person', {autoIncrement: true})
                    objectStore.createIndex('name', 'name', {unique: false})
                    objectStore.createIndex('email', 'email', {unique: true})
                    //createIndex的三個(gè)參數(shù)分別為索引名稱萍启、索引所在的屬性总珠、配置對象(說明該屬性是否包含重復(fù)的值)
                }
                console.log('創(chuàng)建了倉庫', objectStore);
                // return db
            }
        }
    )
}
async function add() {
    let db = await createStore()
    var request = db.transaction(['person'], 'readwrite')
        .objectStore('person')
        .add({ id: 1, name: '張三', age: 24, email: 'zhangsan@example.com' });

    request.onsuccess = function (event) {
        console.log('數(shù)據(jù)寫入成功');
    };

    request.onerror = function (event) {
        console.log('數(shù)據(jù)寫入失敗', event);
    }
}
add()
  • 讀取數(shù)據(jù)
  • 遍歷數(shù)據(jù)
  • 更新數(shù)據(jù)
  • 刪除數(shù)據(jù)
  • 使用索引
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末屏鳍,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子局服,更是在濱河造成了極大的恐慌钓瞭,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腌逢,死亡現(xiàn)場離奇詭異降淮,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)搏讶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門佳鳖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人媒惕,你說我怎么就攤上這事系吩。” “怎么了妒蔚?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵穿挨,是天一觀的道長。 經(jīng)常有香客問我肴盏,道長科盛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任菜皂,我火速辦了婚禮贞绵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘恍飘。我一直安慰自己榨崩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布章母。 她就那樣靜靜地躺著母蛛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪乳怎。 梳的紋絲不亂的頭發(fā)上彩郊,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天,我揣著相機(jī)與錄音蚪缀,去河邊找鬼秫逝。 笑死,一個(gè)胖子當(dāng)著我的面吹牛椿胯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播剃根,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼哩盲,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起廉油,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤惠险,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后抒线,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體班巩,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年嘶炭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了抱慌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,505評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡眨猎,死狀恐怖抑进,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情睡陪,我是刑警寧澤寺渗,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站兰迫,受9級特大地震影響信殊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜汁果,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一涡拘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧须鼎,春花似錦鲸伴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至赡译,卻和暖如春仲吏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蝌焚。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工裹唆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人只洒。 一個(gè)月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓许帐,卻偏偏與公主長得像,于是被迫代替她去往敵國和親毕谴。 傳聞我的和親對象是個(gè)殘疾皇子成畦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評論 2 359

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