面試 | Ajax,fetch,axios的超高頻面試題

推薦閱讀地址

掘金

start

大家好,我是林一一,下面這篇文章是關(guān)于 Ajax,fetch,axios的超高頻面試題,一起來(lái)閱讀吧??

思維導(dǎo)圖

未命名文件.png

一、Ajax

1. 概念

Ajax全稱:async javaScript and xml。xml:是一種可以擴(kuò)展的文本標(biāo)記語(yǔ)言,可以擴(kuò)展自定義的語(yǔ)義標(biāo)簽。很早以前 xml 常用于從服務(wù)端返回?cái)?shù)據(jù)結(jié)構(gòu),現(xiàn)在基本都是使用 json 格式返回?cái)?shù)據(jù)。

2. 作用

在不刷新全局的條件下,局部刷新頁(yè)面。

3. 四步創(chuàng)建 Ajax

  1. 創(chuàng)建 Ajax實(shí)例,let xhr = new XMLHttpRequest(),IE6 不兼容這種寫(xiě)法
  2. 打開(kāi)請(qǐng)求,配置請(qǐng)求前的配置項(xiàng),共 5個(gè)參數(shù),xhr.open([http method], [url], [async], [userName], [userPass])

    http methods 有常用的請(qǐng)求方式有,post, get, delete, put, head, options, trace, connectasync代表異步,默認(rèn)是 true 異步,false 是同步。[url]:是想服務(wù)器請(qǐng)求的 api[userName], [userPass],代表用戶名和密碼

  • http methods 細(xì)分:delete:刪除服務(wù)器端的某些數(shù)據(jù),一般是文件。put:向服務(wù)器上存放某些內(nèi)容,一般是文件,head:只是獲取從服務(wù)器端返回的請(qǐng)求頭信息,不要響應(yīng)主體的內(nèi)容。options:一般用于向服務(wù)器發(fā)送探測(cè)性請(qǐng)求,看是否連接成功
  1. 事件監(jiān)聽(tīng) readystatechange,一般監(jiān)聽(tīng) ajax 狀態(tài)碼發(fā)生改變的事件,這個(gè)事件可以獲取服務(wù)器返回的響應(yīng)主和請(qǐng)求頭。xhr.onreadystatechange = function (){},對(duì)于同步執(zhí)行的 Ajax 請(qǐng)求代碼步驟三要放在send的前面。否則沒(méi)有意義。
  2. 發(fā)送 ajax 請(qǐng)求,ajax 任務(wù)開(kāi)始執(zhí)行。xhr.send([])XMLHttpRequest.send() 方法中如果 Ajax 請(qǐng)求是異步的則這個(gè)方法發(fā)送請(qǐng)求后就會(huì)返回,如果Ajax請(qǐng)求是同步的,那么請(qǐng)求必須知道響應(yīng)后才會(huì)返回。

第五步算上的話,就是讀取返回的數(shù)據(jù) xhr.responseText

// 1. 創(chuàng)建 XMLHttpRequest 實(shí)例
let xhr = XMLHttpRequest()
// 2. 打開(kāi)和服務(wù)器的連接
xhr.open('get', 'URL')
// 3.發(fā)送
xhr.send()
// 4. 接收變化。
xhr.onreadystatechange = () => {
    if(xhr.readyState == 4 && xhr.status == 200){   // readyState: ajax 狀態(tài),status:http 請(qǐng)求狀態(tài)
        console.log(xhr.responseText);   //響應(yīng)主體
    }
}

4. Ajax 狀態(tài)和 HTTP 狀態(tài)碼

  • Ajax 狀態(tài)一共有 5 種 xhr.readyState,分別是 0, 1, 2, 3, 4
  • 狀態(tài) 0:unsent,剛創(chuàng)建的 XMLHttpRequest 實(shí)例,還沒(méi)有發(fā)送。
  • 狀態(tài) 1:(載入)已調(diào)用 send() 方法,正在發(fā)送請(qǐng)求。
  • 狀態(tài) 2:(載入完成)send() 方法執(zhí)行完成,已經(jīng)接收到全部響應(yīng)內(nèi)容
  • 狀態(tài) 3:loading,(交互)正在解析響應(yīng)內(nèi)容
  • 狀態(tài) 4:done,表示響應(yīng)的主體內(nèi)容解析完成,可以在客戶端調(diào)用了
  • HTTP 常見(jiàn)的狀態(tài)碼。
  • 2xx:表示請(qǐng)求已經(jīng)被服務(wù)器接收,理解,請(qǐng)接受。常見(jiàn)的有,200 表示ok,表示服務(wù)能夠返回信息。204 No Content 無(wú)內(nèi)容。服務(wù)器成功處理,但未返回內(nèi)容。
  • 3xx:一類重要的高頻考點(diǎn),301:表示永久轉(zhuǎn)移,返回舊域名會(huì)跳轉(zhuǎn)到心域名。302:臨時(shí)轉(zhuǎn)移。一般用于服務(wù)器負(fù)載均衡,但服務(wù)器的并發(fā)數(shù)達(dá)到最大時(shí),服務(wù)器會(huì)將后續(xù)訪問(wèn)的用戶轉(zhuǎn)移到其他服務(wù)器上去。307:表示臨時(shí)重定向。304:表示不設(shè)置緩存,對(duì)于不經(jīng)常更新的文件,例如css/js/html文件,服務(wù)器會(huì)結(jié)合客戶端設(shè)置304狀態(tài),加載過(guò)的資源下次請(qǐng)求時(shí)會(huì)在客戶端中獲取。
  • 4xx:表示語(yǔ)義有誤,請(qǐng)求無(wú)法被服務(wù)器端理解。400:表示請(qǐng)求的參數(shù)錯(cuò)誤。401:表示無(wú)權(quán)限訪問(wèn)。404:表示請(qǐng)求的資源不存在。413:表示和服務(wù)器的交互過(guò)大。
  • 5xx:服務(wù)器端出錯(cuò)。500:表示服務(wù)器端出現(xiàn)未知的錯(cuò)誤。503:服務(wù)器超負(fù)荷。

5. ajax 中常用的屬性和方法

  1. onabort: 表示請(qǐng)求中斷后要處理的事。和 xhr.abort() 一起使用。
  2. ontimeout: 表示請(qǐng)求的超時(shí),執(zhí)行的方法。和timeout設(shè)定的事件一起使用。
  3. response: 響應(yīng)的主體內(nèi)容。
  4. responseText: 響應(yīng)的具體內(nèi)容是字符串,一般是 json 字符串
  5. responseXML: 響應(yīng)的具體內(nèi)容是文檔。
  6. status: http 的狀態(tài)碼。
  7. statusText: 狀態(tài)碼描述
  8. withCredentials:表示是否允許跨域。
  9. getAllResponseHeaders:獲取所有響應(yīng)頭信息。
  10. xhr.open():打開(kāi)URL請(qǐng)求。
  11. xhr.send():表示發(fā)送 ajax。
  12. setRequestHeader(): 設(shè)置請(qǐng)求頭。這個(gè)屬性在必須在xhr.open()后面。

思考

  1. postget 有什么區(qū)別。

http 的所有請(qǐng)求方法中都可以從服務(wù)端獲取數(shù)據(jù),和傳遞內(nèi)容。get:主要是從服務(wù)器獲取數(shù)據(jù)。post 主要發(fā)送數(shù)據(jù)給服務(wù)器。
GETPOST 本質(zhì)上就是 TCP 鏈接,并無(wú)差別,但是由于HTTP的規(guī)定和瀏覽器/服務(wù)器的限制具體由如下的區(qū)別

  • 緩存的角度上說(shuō),get 請(qǐng)求會(huì)被瀏覽器默認(rèn)緩存下來(lái),而 post 請(qǐng)求默認(rèn)不會(huì)。
  • 參數(shù)來(lái)說(shuō),get 請(qǐng)求的參數(shù)一般放在 url 中,post 請(qǐng)求是放在請(qǐng)求主體中,因此post請(qǐng)求更安全一些。
  • TCP 上來(lái)說(shuō),GET 產(chǎn)生一個(gè) TCP 數(shù)據(jù)包;POST 產(chǎn)生兩個(gè) TCP 數(shù)據(jù)包。對(duì)于GET方式的請(qǐng)求,瀏覽器會(huì)把http headerdata一并發(fā)送出去,服務(wù)器響應(yīng)200(返回?cái)?shù)據(jù));而對(duì)于POST,瀏覽器先發(fā)送header,服務(wù)器響應(yīng) 100 continue,瀏覽器再發(fā)送data,服務(wù)器響應(yīng)200 ok(返回?cái)?shù)據(jù))。雖然 post 請(qǐng)求需要發(fā)送兩次,但是時(shí)間上是基本差別不大的。還有并不是所有瀏覽器都會(huì)在POST中發(fā)送兩次包,Firefox 就只發(fā)送一次
  1. 來(lái)一道思考題,求輸出結(jié)果
let xhr = new XMLHttpRequest()
xhr.open('post', 'api')
xhr.onreadystatechange = () =>{
    if(xhr.readyState == 2){
        console.log(2)
    }
    if(xhr.readyState == 4){
        console.log(4)
    }
}
xhr.send()
console.log(3)
/* 輸出
*   3 2 4
*/

如果知道任務(wù)隊(duì)列的概念,不難知道輸出的結(jié)果,因?yàn)槭钱惒秸?qǐng)求,所以同步的主任務(wù)先輸出3,最后輸出 2, 4。如果上面xhr.open('post', 'api') 變成 xhr.open('post', 'api', false) 后代碼就是同步的,任務(wù)隊(duì)列中只有主任務(wù)輸出的結(jié)果變成2, 4, 3

  1. 再來(lái)一道思考題,在同步請(qǐng)求中下面代碼輸出的是什么
let xhr = new XMLHttpRequest()
xhr.open('get', 'xxx', false)
xhr.send()

xhr.onreadystatechange = () => {
    console.log(xhr.readyState)
}

上面的結(jié)果什么也沒(méi)有輸出,這里涉及到任務(wù)隊(duì)列的知識(shí),onreadystatechange 這個(gè)事件監(jiān)聽(tīng)的是 ajax 狀態(tài)碼的變化,上面的同步請(qǐng)求中 xhr.send() 已經(jīng)執(zhí)行完后 ajax 的狀態(tài)碼由 0 變成了 4 還沒(méi)有執(zhí)行到 onreadystatechange 這個(gè)監(jiān)聽(tīng)事件,所以沒(méi)有輸出結(jié)果。如果將監(jiān)聽(tīng)事件放在 xhr.send() 之前,那么輸出的就是 4。

二、axios

axios 是使用 promise 封裝的 ajax。axios 不是一個(gè)類是一個(gè)方法。

1. axios 屬性

axios 有 get, post, put, patch ,delete 等請(qǐng)求方式,get,post 返回的實(shí)例都是 promise,所以可以使用 promise 的方法,下面給出基本的實(shí)用方法。

  • axios.get(),向服務(wù)器發(fā)送一個(gè) get 請(qǐng)求。
axios.get('apiURL', {
    param: {
        id: 1
    }
}).then(res=>{
    console.log(res);
})
.catch( error=>{
    console.log(error)
}

param 中的的鍵值對(duì)最終會(huì) ? 的形式,拼接到請(qǐng)求的鏈接上,發(fā)送到服務(wù)器。

  • axios.post()示例
axios.post('apiURL',{
        user: '林一一',
        age: 18
}).then( res=>{
    console.log(res);
})
.catch( error=>{
    console.log(error)
}
  • axios.put()示例
axios.put('apiURL', {
    name: '林一一',
})
  • axios.patch(url[, data[, config]])示例
axios.patch('apiURL', {
    id: 13,
},{
   timeout: 1000,
})
  • axios.delete()示例
axios.delete('apiURL', {
    params: {
        id: 1
    },
    timeout: 1000
})

2. 一次并發(fā)的請(qǐng)求 axios.all([])

axios.all() 可以實(shí)現(xiàn)多個(gè)請(qǐng)求,且請(qǐng)求都需要在完成后才再去做某事。

let requestArr = [axios.get('apiURL/1'), axios.get('apiURL/2'), axios.post('apiURL/3', {id: 3})]
axios.all(requestArr).then(res => {
    console.log(res)
})

思考,axios.all() 是怎么實(shí)現(xiàn)并發(fā)請(qǐng)求的?

axios.all() 使用的是 promise.all() 實(shí)現(xiàn)的,來(lái)看看 axios 中的源碼

axios.all = function all(promises) {
    return Promise.all(promises);
};

3. axios 中的配置項(xiàng)。

實(shí)用的 axios配置項(xiàng)

三、fetch

1. 介紹 fetch

  • fetch:是 http 的數(shù)據(jù)請(qǐng)求方式,是 XMLHttpRequest 的一種代替方案,沒(méi)有使用到 XMLHttpRequest 這個(gè)類。fetch 不是 ajax,而是原生的 js。fetch() 使用 Promise,不使用回調(diào)函數(shù)。fetch 是 ES8 中新增的 api,兼容性不是很好,IE 完全不兼容 fetch 寫(xiě)法。
  • fetch() 采用模塊化設(shè)計(jì),API 分散在 Response 對(duì)象、Request 對(duì)象、Headers 對(duì)象上。
  • fetch() 通過(guò)數(shù)據(jù)流(Stream 對(duì)象)處理數(shù)據(jù),對(duì)于請(qǐng)求大文件或者網(wǎng)速慢的場(chǎng)景相當(dāng)有用。XMLHttpRequest 沒(méi)有使用數(shù)據(jù)流,所有的請(qǐng)求都必須完成后才拿到
  • 在默認(rèn)情況下 fetch 不會(huì)接受或者發(fā)送 cookies

2. fetch(url, optionObj) 基本使用

  • 接收第一個(gè)參數(shù)為請(qǐng)求的 url,默認(rèn)的請(qǐng)求方式是 get
  • 第二個(gè)是可選參數(shù) optionObj,可以控制不同配置的屬性,比如 method:屬性是字符串。headers: 一個(gè)對(duì)象,可以設(shè)定 http 的請(qǐng)求頭。body: POST 請(qǐng)求的數(shù)據(jù)體,屬性也是字符串。credentials 表示是否可以攜帶 cookieincludes表示是否同源都包含 cookie
  • fetch 參數(shù)沒(méi)有同步的設(shè)定,因?yàn)?fetch 是基于 promise 封裝的本身就是異步。
  • fetch 雖然使用的是 promise 封裝的,但是 catch 函數(shù)不能直接的捕獲到錯(cuò)誤,需要在第一個(gè) then 函數(shù)內(nèi)做些操作。

fetch 發(fā)送 post請(qǐng)求時(shí),當(dāng)發(fā)生的是跨域請(qǐng)求,fetch 會(huì)先發(fā)送一個(gè) OPTIONS 請(qǐng)求,來(lái)確認(rèn)服務(wù)器是否允許接受請(qǐng)求,這個(gè)請(qǐng)求主要是用來(lái)詢問(wèn)服務(wù)器是否允許修改header頭等一些操作。服務(wù)器同意后返回 204,才會(huì)發(fā)送真正的請(qǐng)求。沒(méi)有發(fā)生跨域的情況下不會(huì)產(chǎn)生兩次請(qǐng)求。

一個(gè) get 請(qǐng)求

const pro = fetch('https://lyypro.gitee.io/blog/')
pro.then( response => 
    response.json()
).catch( err => {
    console.log(err)
})

一個(gè) post 請(qǐng)求

const URL =  'https://lyypro.gitee.io/blog/'
const init = {
    method: 'POST',
    header: {
        "Content-type": "application/x-www-form-urlencoded; charset=UTF-8",
    },
    data: 'id=12&name=林一一',
    credentials: 'include'
}
const pro = fetch(URL, init)
pro.then( response => 
    response.json()
).catch( err => {
    console.log(err)
})

上面的請(qǐng)求都可以使用 await, async 來(lái)修改這里不展示。同時(shí)是為 post 請(qǐng)求中,data 屬性只支持字符串,我們可以使用

4. fetch 的三個(gè)模塊

  • Response 模塊:fetch 請(qǐng)求發(fā)送后,會(huì)得到一個(gè)服務(wù)器的響應(yīng) response,這個(gè)響應(yīng)對(duì)于著 http 的回應(yīng)。
  • Request 模塊:這是用于請(qǐng)求服務(wù)器的模塊,上面提到的 data, header, method 都是 Request 模塊的屬性。
  • Headers,這是一個(gè)在 Response.headers上的屬性用于操控響應(yīng)頭的信息。

上面三者的詳細(xì)屬性可以看看 阮老師的 Fetch API 教程

5.思考 發(fā)送 post 2 次請(qǐng)求的原因

使用 fetch 發(fā)送 post 請(qǐng)求時(shí)如果是跨域,那么導(dǎo)致 fetch 第一次發(fā)送了一個(gè)Options 請(qǐng)求,詢問(wèn)服務(wù)器是否支持修改的請(qǐng)求頭,如果服務(wù)器支持,則在第二次中發(fā)送真正的請(qǐng)求。

6.思考 fetch 的缺點(diǎn)

  1. fetchget/head 請(qǐng)求不能設(shè)置 body 屬性。
  2. fetch 請(qǐng)求后,服務(wù)器返回的狀態(tài)碼無(wú)論是多少包括(4xx, 5xx),fetch 都不認(rèn)為是失敗的,也就是使用 catch 也不能直接捕捉到錯(cuò)誤,需要再第一個(gè) then 中做一些處理。

四、面試題

封裝原生的 Ajax

1.實(shí)現(xiàn)一個(gè) Ajax。

將原生的 ajax 封裝成 promise

var myNewAjax = function (url) {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open('get', url);
        xhr.send(data);
        xhr.onreadystatechange = function () {
            if (xhr.status == 200 && readyState == 4) {
                var json = JSON.parse(xhr.responseText);
                resolve(json)
            } else if (xhr.readyState == 4 && xhr.status != 200) {
                reject('error');
            }
        }
    })
}

2. ajax 有幾個(gè)狀態(tài),分別代表什么?

ajax 5個(gè)狀態(tài)向上看。

3. fetch VS ajax VS axios 區(qū)別

  • 傳統(tǒng)的 ajax 利用的是 XMLHttpRequest 這個(gè)對(duì)象,和后端進(jìn)行交互。JQuery ajax 是對(duì)原生 XHR 的封裝,多請(qǐng)求間有簽到的話就會(huì)出現(xiàn)回調(diào)地獄的問(wèn)題。
  • axios 使用 promise 封裝 xhr,解決了回調(diào)地獄問(wèn)題
  • fetch 不是 XMLHttpRequestfetch 是原生的 js,使用的是 promise

4. Fetch 和 Ajax 比有什么優(yōu)點(diǎn)?

fetch 使用的是 promise 方便使用異步,沒(méi)有回調(diào)地獄的問(wèn)題。

5. 如何實(shí)現(xiàn)一個(gè) ajax 請(qǐng)求?如果我想發(fā)出兩個(gè)有順序的 ajax 需要怎么做?

實(shí)現(xiàn) ajax 的請(qǐng)求就是上面的創(chuàng)建 ajax 的逼格步驟。實(shí)現(xiàn)兩個(gè)有順序的 ajax 可以使用 promise.then()

6. Ajax 怎么解決瀏覽器緩存問(wèn)題

  • 設(shè)置請(qǐng)求頭,在 ajax 發(fā)送請(qǐng)求前加上 anyAjaxObj.setRequestHeader("If-Modified-Since","0")anyAjaxObj.setRequestHeader("Cache-Control","no-cache")
  • 在 URL 后面加上一個(gè)隨機(jī)數(shù):"fresh=" + Math.random()。 或在后面加上時(shí)間搓:"nowtTime=" + new Date().getTime()
  • 如果是使用 jQuery,直接這樣就可以了 $.ajaxSetup({cache:false})。這樣頁(yè)T面的所有 ajax 都會(huì)執(zhí)行這條語(yǔ)句就是不需要保存緩存記錄。

五、參考

get和post的區(qū)別

Fetch API 教程

MDN XMLHttpRequest

MDN fetch

六、結(jié)束

感謝閱讀到這里,如果著篇文章能對(duì)你有一點(diǎn)啟發(fā)或幫助的話歡迎 star, 我是林一一,下次見(jiàn)。

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

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