【綜-網(wǎng)】Http淺析【2】——ajax跨域問(wèn)題

視頻參考:ajax跨域完全講解

本文精華版:【綜合】ajax跨域問(wèn)題

什么是跨域問(wèn)題

簡(jiǎn)單來(lái)講虏束,當(dāng)前臺(tái)調(diào)用后臺(tái),如果接口不是一個(gè)域時(shí),就會(huì)產(chǎn)生跨域問(wèn)題。

由于目前前后端分離的技術(shù)架構(gòu)液茎,前臺(tái)項(xiàng)目和后臺(tái)項(xiàng)目都是獨(dú)立開(kāi)發(fā)進(jìn)行的逞姿。當(dāng)聯(lián)調(diào)測(cè)試時(shí)辞嗡,前臺(tái)頁(yè)面必然會(huì)大量調(diào)用后臺(tái)的接口,此時(shí)如果接口不是同一個(gè)域滞造,就會(huì)發(fā)生跨域問(wèn)題续室。

測(cè)試環(huán)境搭建

【后臺(tái)環(huán)境搭建】

使用node+express搭建一個(gè)后臺(tái)系統(tǒng)
(1)新建一個(gè)文件夾NodeBack,輸入 npm init 初始化項(xiàng)目谒养,創(chuàng)建index.js作為整個(gè)后臺(tái)的入口文件

(2)安裝express:npm install express --save

(3)安裝body-parse:npm install body-parse--save挺狰,用于解析post請(qǐng)求的參數(shù)

(4)編寫入口文件 index.js

var express = require('express');

/**
 * 解析post來(lái)的參數(shù)
 app.use(bodyParser.json()); // for parsing application/json
 app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
 * */

var bodyParser = require('body-parser');

var app = express();

app.use(bodyParser.urlencoded({extended: true})); // for parsing application/x-www-form-urlencoded

app.get('/test', function (req, res) {
  var name = req.query.name
  var age = req.query.age
  res.jsonp({
    data:'name is ' + name + "| age is " + age
  });
});

app.post('/login', function (req, res) {
  var name = req.body.name
  var password = req.body.password
  if (password === "123") {
    res.jsonp({
      "name": name,
      "password": password
    });
  } else {
    res.send("error!");
  }
});

var server = app.listen(3005, function () {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});
GET請(qǐng)求
POST 請(qǐng)求

【前臺(tái)請(qǐng)求頁(yè)面】


簡(jiǎn)單html版

簡(jiǎn)單起見(jiàn),就使用Jquery來(lái)發(fā)送前臺(tái)請(qǐng)求

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>

  <!--導(dǎo)入jquery-->
  <script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<a href="#" onclick="getReq()">發(fā)送get請(qǐng)求</a>

<script>
  function getReq(){
    $.getJSON("http://localhost:3005/test?name=hugo&&age=18")
      .then((result)=>{
        console.log(result)
    })
  }
</script>
</body>
</html>

使用firefox买窟,打開(kāi)此網(wǎng)址丰泊,按F12,調(diào)出控制臺(tái)始绍,點(diǎn)擊發(fā)出get請(qǐng)求


但是在控制臺(tái)發(fā)現(xiàn)報(bào)錯(cuò)提示瞳购,這就是跨域問(wèn)題

ajax跨域問(wèn)題分析

發(fā)生跨域問(wèn)題有三個(gè)原因:
【1】瀏覽器限制:很多同學(xué)認(rèn)為跨域問(wèn)題的是服務(wù)器后臺(tái)不允許前臺(tái)跨域訪問(wèn),但一些情況下并不是這樣亏推,還有可能是瀏覽器多管閑事学赛,處于安全考慮限制了跨域訪問(wèn)。

如何驗(yàn)證這種想法呢吞杭,我們可以在get請(qǐng)求中增加一句log

app.get('/test', function (req, res) {
  var name = req.query.name
  var age = req.query.age
  res.jsonp({
    data:'name is ' + name + "| age is " + age
  });
  console.log("receive get request")
});

再次發(fā)送請(qǐng)求:



發(fā)現(xiàn)響應(yīng)都是沒(méi)有任何問(wèn)題的

【2】跨域盏浇,地址中,協(xié)議芽狗、域名绢掰、端口任意一個(gè)不一樣,瀏覽器就認(rèn)為是跨域

【3】XHR(XMLHttpRequest)請(qǐng)求童擎。請(qǐng)求的type為XHR滴劲,非json、img等其他類型柔昼。
當(dāng)上述三種情況同時(shí)滿足時(shí)哑芹,跨域問(wèn)題就產(chǎn)生了,

解決思路

【1】解決瀏覽器限制:通過(guò)指定瀏覽器的啟動(dòng)參數(shù)捕透,解除限制聪姿,但是這種情況需要用戶手動(dòng)操作碴萧,所以交互不友好,所以不推薦使用

【2】轉(zhuǎn)變請(qǐng)求的類型末购。上面說(shuō)到破喻,只有請(qǐng)求類型是xhr時(shí),將xhr的類型轉(zhuǎn)化為jsonp的格式

【3】跨域盟榴。
被調(diào)用(服務(wù)器)方支持跨域曹质;
調(diào)用方做跨域支持(隱藏跨域):通過(guò)代理,從瀏覽器發(fā)送出的請(qǐng)求都是同源請(qǐng)求

全面解決跨域問(wèn)題

【禁止瀏覽器檢查跨域】

不做介紹擎场,因?yàn)閷?shí)用價(jià)值不大羽德。

【jsonp解決跨域】

json for pending :利用js請(qǐng)求資源標(biāo)簽時(shí),請(qǐng)求可以跨域迅办,來(lái)解決跨域請(qǐng)求宅静,它是一種變通的解決方案。

function jsonpReq(){
    var result
    $.ajax({
      url:"http://localhost:3005/test?name=hugo&&age=18",
      dataType:'jsonp',
      success:function(json){
        result=json
        console.log(result)
      }
    })
  }

在使用jsonp的時(shí)候站欺,后臺(tái)需要做改動(dòng)(java后臺(tái))姨夹,不然服務(wù)器返回的內(nèi)容,瀏覽器會(huì)當(dāng)做js代碼來(lái)解析矾策,會(huì)報(bào)語(yǔ)法錯(cuò)誤磷账。經(jīng)測(cè)試,node編寫的后臺(tái)無(wú)需添加額外的內(nèi)容贾虽。

我們對(duì)jsonp的原理進(jìn)行分析逃糟,解釋為什么java后臺(tái)需要進(jìn)行額外設(shè)置:


首先,看一下jsonp發(fā)送的報(bào)文類型是script榄鉴,在之前分析跨域問(wèn)題產(chǎn)生的條件之一就是請(qǐng)求報(bào)文的類型是xhr履磨,那么jsonp的思路就是改變報(bào)文的請(qǐng)求類型,變?yōu)閟cript庆尘。

第二剃诅,普通的ajax請(qǐng)求返回的json對(duì)象,而jsonp返回的是js腳本


第三驶忌,jsonp發(fā)送的url后面接了一串額外的callback字符

i

那么從這里我們就能簡(jiǎn)單分析jsonp的原理是:jsonp發(fā)送的url請(qǐng)求自動(dòng)添加了一個(gè)callback參數(shù)矛辕,當(dāng)后臺(tái)發(fā)現(xiàn)callback參數(shù)時(shí),就認(rèn)為是一個(gè)jsonp請(qǐng)求付魔,響應(yīng)頭在返回?cái)?shù)據(jù)時(shí)聊品,數(shù)據(jù)格式就由json變成script,而script的內(nèi)容就是一個(gè)函數(shù)調(diào)用几苍。

那么java后臺(tái)的改動(dòng)就能分析得出如下:


所以翻屈,如果我們把url請(qǐng)求中的callback改成callback2,那么后臺(tái)就不會(huì)認(rèn)為前臺(tái)請(qǐng)求是一個(gè)jsonp請(qǐng)求妻坝。即:前臺(tái)調(diào)用的“callback”和后臺(tái)的“callback”實(shí)際上是一個(gè)接口上的協(xié)議伸眶,需要保持一致惊窖。

很明顯,Jsonp是基于Jquery的一種解決方案厘贼,但是在react界酒、vue這類本身的是要替代Jquery操作dom結(jié)構(gòu)的框架,效果可想而知嘴秸。

接下來(lái)毁欣,再來(lái)談?wù)刯sonp的利弊:

1、服務(wù)器端需要改動(dòng)岳掐。當(dāng)服務(wù)器是第三方提供時(shí)凭疮,這種做法就會(huì)出現(xiàn)局限性。
2岩四、只支持GET請(qǐng)求哭尝,通過(guò)分析原理,我們知道jsonp是通過(guò)Jquery動(dòng)態(tài)創(chuàng)建一個(gè)script來(lái)創(chuàng)建一個(gè)請(qǐng)求的剖煌,所以請(qǐng)求類型就被局限在了GET。
3逝淹、 發(fā)送的不是XHR請(qǐng)求耕姊,即XHR的諸多特性都無(wú)法使用,例如異步栅葡、事件機(jī)制都無(wú)法使用茉兰。

綜上可見(jiàn),我們?cè)诮鉀Q跨域問(wèn)題時(shí)欣簇,最好方法還是解決請(qǐng)求是跨域的规脸,而不是改變請(qǐng)求是XHR還是JSONP

下面就繼續(xù)介紹本文的重點(diǎn):【讓服務(wù)器支持跨域】熊咽、【前臺(tái)請(qǐng)求隱藏跨域】

【從系統(tǒng)架構(gòu)分析跨域】

最常見(jiàn)的javaee 架構(gòu)


請(qǐng)求流程:
請(qǐng)求從瀏覽器發(fā)出莫鸭,首先到apache或nginx(靜態(tài)服務(wù)器) ,然后判斷客戶端請(qǐng)求是靜態(tài)請(qǐng)求還是動(dòng)態(tài)請(qǐng)求横殴。

簡(jiǎn)單講被因,跟客戶端數(shù)據(jù)有關(guān)系的就是動(dòng)態(tài)數(shù)據(jù)(用戶信息,消息列表等)衫仑,而圖片梨与、js、css文狱、html等就是靜態(tài)請(qǐng)求粥鞋。

如果是靜態(tài)請(qǐng)求,靜態(tài)服務(wù)器直接處理瞄崇,然后把數(shù)據(jù)返回給客戶端呻粹。如果是動(dòng)態(tài)請(qǐng)求到踏,則轉(zhuǎn)發(fā)給后臺(tái)的應(yīng)用>服務(wù)器,處理完畢后尚猿,應(yīng)用服務(wù)器把數(shù)據(jù)返回給靜態(tài)服務(wù)窝稿,隨后靜態(tài)服務(wù)器發(fā)送給客戶端。

中間的http服務(wù)器凿掂,一般有兩個(gè)作用:
(1)處理靜態(tài)請(qǐng)求
(2)轉(zhuǎn)發(fā)動(dòng)態(tài)請(qǐng)求和負(fù)載均衡伴榔。

那么在看跨域請(qǐng)求時(shí)的兩種思路:

第一:直接從瀏覽器里發(fā)出請(qǐng)求到被調(diào)用方的http服務(wù)器。 這時(shí)需要在http服務(wù)器上做響應(yīng)的修改庄萎,這些修改都是基于http請(qǐng)求關(guān)于跨域部分的協(xié)議踪少。就是在返回頭里增加一些字段,告訴瀏覽器被調(diào)用方允許客戶端跨域訪問(wèn)糠涛。這樣瀏覽器就不會(huì)報(bào)跨域的問(wèn)題援奢。


第二:隱藏跨域。請(qǐng)求不直接從瀏覽器發(fā)出忍捡,而是從中間http服務(wù)器轉(zhuǎn)出集漾。通過(guò)服務(wù)器的轉(zhuǎn)發(fā),瀏覽器不會(huì)發(fā)現(xiàn)所有的請(qǐng)求都是同一個(gè)域砸脊。即調(diào)用方會(huì)發(fā)現(xiàn)所有的請(qǐng)求都是從本地的http服務(wù)器發(fā)出(其實(shí)并不是具篇,請(qǐng)求都是經(jīng)過(guò)客戶端http服務(wù)器的轉(zhuǎn)發(fā))

跨域解決方向-被調(diào)用方解決-Filter及spring解決方案

這是基于支持跨域的解決思路,是基于http協(xié)議關(guān)于跨域方面的一些規(guī)定凌埂,在響應(yīng)頭里增加指定的字段驱显,告訴瀏覽器服務(wù)端支持跨域調(diào)用。 此種情況下瞳抓,瀏覽器直接發(fā)送請(qǐng)求到服務(wù)方埃疫。

在據(jù)圖解釋此方案前,我們理清幾個(gè)問(wèn)題:

瀏覽器如何判斷是否跨域孩哑?

答:通過(guò)對(duì)比普通請(qǐng)求和跨域請(qǐng)求瀏覽器里的請(qǐng)求頭里的內(nèi)容栓霜,可以發(fā)現(xiàn)跨域請(qǐng)求中增加了一個(gè)origin字段,字段值為當(dāng)前域名的信息臭笆。也就是說(shuō)叙淌,當(dāng)瀏覽器發(fā)現(xiàn)請(qǐng)求是跨域時(shí),就會(huì)在請(qǐng)求頭添加origin的字段愁铺。當(dāng)瀏覽器接收到響應(yīng)頭后鹰霍,就會(huì)檢查里面是否有允許跨域的字段,如果沒(méi)有茵乱,就會(huì)報(bào)錯(cuò)茂洒。

瀏覽器是先執(zhí)行?還是先判斷瓶竭?

答:瀏覽器發(fā)送跨域請(qǐng)求給后臺(tái)督勺,后臺(tái)日志打印正常渠羞,瀏覽器響應(yīng)狀態(tài)碼為200,但卻報(bào)跨域問(wèn)題智哀,說(shuō)明瀏覽器是先執(zhí)行請(qǐng)求操作次询,然后在判斷是否跨域。那么瓷叫,是不是所有的請(qǐng)求都是先執(zhí)行后判斷呢屯吊?

并不是的,這就引出了簡(jiǎn)單請(qǐng)求和非簡(jiǎn)單請(qǐng)求的概念摹菠。

簡(jiǎn)單請(qǐng)求和非簡(jiǎn)單請(qǐng)求

每次瀏覽器再發(fā)送請(qǐng)求時(shí)盒卸,會(huì)做一次判斷,如果是簡(jiǎn)單請(qǐng)求次氨,那么就是先執(zhí)行再判斷蔽介。如果是非簡(jiǎn)單請(qǐng)求,那么瀏覽器會(huì)先發(fā)送一個(gè)預(yù)檢頭煮寡,檢查通過(guò)后虹蓄,瀏覽器才會(huì)發(fā)送真正的請(qǐng)求

跨域解決——服務(wù)器端實(shí)現(xiàn)【Spring 編寫的后臺(tái)】

基于注解,可以使用

@CrossOrigin

那么被注解類下的所有請(qǐng)求方法都是可以支持跨域的

跨域解決——服務(wù)器端實(shí)現(xiàn)【Spring boot 編寫的后臺(tái)】

這里我們需要了解http協(xié)議關(guān)于跨域方面所有的要求洲押,針對(duì)不同的場(chǎng)景返回不同的頭武花。只有知道了所有的響應(yīng)頭,我們才能在后面的http服務(wù)器上配置響應(yīng)頭杈帐。

首先需要注冊(cè)一個(gè)filterRegistrationBean ,然后讓所有的請(qǐng)求都經(jīng)過(guò)這filter

接下來(lái)我們?cè)?strong>CrosFilter里的doFilter方法中添加服務(wù)器響應(yīng)頭

對(duì)于非簡(jiǎn)單請(qǐng)求专钉,我們?cè)诎凑丈鲜龇椒ㄌ砑禹憫?yīng)頭后挑童,可能會(huì)出現(xiàn)如下的錯(cuò)誤:


意思是我們的返回頭缺少“access-control-allow-headers”是缺少的。

所以我們需要在后臺(tái)服務(wù)器中再增加一行代碼:

res.addHeader("Access-Control-Allow-Headers","Content-type");

在上面我們分析了什么是簡(jiǎn)單請(qǐng)求和非簡(jiǎn)單請(qǐng)求跃须,那么在非簡(jiǎn)單請(qǐng)求的情況下站叼,瀏覽器會(huì)發(fā)送兩次請(qǐng)求:


這樣會(huì)影響請(qǐng)求的效率。http協(xié)議中增添了一個(gè)請(qǐng)求頭菇民,對(duì)預(yù)檢頭緩存尽楔。

res.addHeader("Access-Control-Max-Age","3600");

告訴瀏覽器緩存預(yù)檢頭,時(shí)間為3600s第练。那么當(dāng)再次發(fā)送跨域請(qǐng)求時(shí)阔馋,就只會(huì)請(qǐng)求一次。

問(wèn)題:*代表所有的Url請(qǐng)求娇掏,那么是不是在任何情況下都沒(méi)有問(wèn)題呢呕寝?

帶自定義頭的跨域

當(dāng)我們直接在跨域請(qǐng)求中添加自定義請(qǐng)求頭時(shí)(假設(shè)自定義請(qǐng)求頭為x-header1和x-header2),可能會(huì)報(bào)如下錯(cuò)誤:


這里的解決辦法是將自定義的請(qǐng)求頭添加到Access-Control_Allow-Headers:

res.addHeader("Access-Control_Allow-Headers","Content-type,x-header1,x-header2");

當(dāng)然我們也可以動(dòng)態(tài)地設(shè)置headers


跨域解決——服務(wù)器端實(shí)現(xiàn)【Node.js 編寫的后臺(tái)】

跨域解決方向-被調(diào)用方解決-Http服務(wù)器解決方案

【Nginx配置】

Nginx配置文件:


【apache配置】

相當(dāng)于把之前在nginx上的配置婴梧,再在apache上配置一下下梢,思路也是和nginx一樣的客蹋。由于apache配置比較復(fù)雜,詳細(xì)配置請(qǐng)參考其他文章孽江。

跨域解決方向-調(diào)用方解決

這是基于隱藏跨域的解決思路讶坯。此種情況下,請(qǐng)求不會(huì)直接從瀏覽器發(fā)送到被調(diào)用方岗屏,而是從調(diào)用方的http服務(wù)器轉(zhuǎn)發(fā)過(guò)去的(被調(diào)用方http服務(wù)器或者應(yīng)用服務(wù)器接收)辆琅。使用了反向代理技術(shù),在瀏覽器上是看不到任何跨域請(qǐng)求担汤。

這里就和上述apache和nginx操作類型涎跨,需要修改他們的配置文件(反向代理的配置)。本文只做簡(jiǎn)單的配置解釋崭歧,詳細(xì)內(nèi)容請(qǐng)小伙伴們自行百度隅很。

Nginx反向代理

首先我們修改一下host,其效果是當(dāng)你在瀏覽器訪問(wèn) www.a.comwww.b.com時(shí)率碾,url地址會(huì)映射到127.0.0.1上

接下來(lái)配置Nginx配置


然后客戶端在進(jìn)行網(wǎng)絡(luò)請(qǐng)求時(shí)叔营,需要變成nginx代理之后的地址,也就是

/ajaxserver

可以發(fā)現(xiàn)所宰,此時(shí)調(diào)用的url就是本域的地址(瀏覽器看到的是相對(duì)地址)绒尊,自然就不存在了跨域問(wèn)題。

apache反向代理配置

思路:增加一個(gè)虛擬主機(jī)仔粥,然后讓此虛擬主機(jī)婴谱,把我們的跨域請(qǐng)求作反向代理

總結(jié)

至此,本文簡(jiǎn)單分析了一下跨域問(wèn)題產(chǎn)生的原因和常見(jiàn)的解決方法躯泰,如果有什么問(wèn)題歡迎留言交流討論~

筆者個(gè)人訂閱號(hào)~歡迎小伙伴們關(guān)注


微信公眾號(hào)-感謝關(guān)注

若有疑問(wèn)可以QQ聯(lián)系筆者谭羔,雖然不一定100%解決你的問(wèn)題,但是可以交流探討一波:2276604211

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末麦向,一起剝皮案震驚了整個(gè)濱河市瘟裸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌诵竭,老刑警劉巖话告,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異卵慰,居然都是意外死亡沙郭,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門呵燕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)棠绘,“玉大人,你說(shuō)我怎么就攤上這事⊙醪裕” “怎么了夜矗?”我有些...
    開(kāi)封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)让虐。 經(jīng)常有香客問(wèn)我紊撕,道長(zhǎng),這世上最難降的妖魔是什么赡突? 我笑而不...
    開(kāi)封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任对扶,我火速辦了婚禮,結(jié)果婚禮上惭缰,老公的妹妹穿的比我還像新娘浪南。我一直安慰自己,他們只是感情好漱受,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布络凿。 她就那樣靜靜地躺著,像睡著了一般昂羡。 火紅的嫁衣襯著肌膚如雪絮记。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天虐先,我揣著相機(jī)與錄音怨愤,去河邊找鬼。 笑死蛹批,一個(gè)胖子當(dāng)著我的面吹牛撰洗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播腐芍,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼了赵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了甸赃?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤冗酿,失蹤者是張志新(化名)和其女友劉穎埠对,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體裁替,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡项玛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了弱判。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片襟沮。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出开伏,到底是詐尸還是另有隱情膀跌,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布固灵,位于F島的核電站捅伤,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏巫玻。R本人自食惡果不足惜丛忆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望仍秤。 院中可真熱鬧熄诡,春花似錦、人聲如沸诗力。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)姜骡。三九已至导坟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間圈澈,已是汗流浹背惫周。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留康栈,地道東北人递递。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像啥么,于是被迫代替她去往敵國(guó)和親登舞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

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