瀏覽器的同源策略詳解

一壶笼、同源策略

同源策略是一種約定,是瀏覽器最核心也最基本的安全功能雁刷,主要體現(xiàn)在同源策略會(huì)限制來(lái)自不同源的文檔和腳本對(duì)當(dāng)前源的文檔數(shù)據(jù)的讀取或設(shè)置某些屬性覆劈,是用于隔離潛在惡意文件的重要安全機(jī)制。

二、如何確定一個(gè)源

只要滿足下面三項(xiàng)相同墩崩,則可以確定兩個(gè)頁(yè)面是來(lái)自同一個(gè)源的

協(xié)議氓英、域名、端口

下面給出相對(duì)http://abc.jjp.com/app/page.html的同源檢測(cè)結(jié)果

url 結(jié)果 原因
http://abc.jjp.com/app/page2.html 成功
http://abc.jjp.com/source/page2.html 成功
https://abc.jjp.com/app/dist/page3.html 失敗 協(xié)議不相同
http://efg.jjp.com/app/page2.html 失敗 域名不相同
http://abc.jjp.com:8080/app/page2.html 失敗 端口不相同

三鹦筹、源的繼承

about:blank铝阐,javascript:中的內(nèi)容,繼承了將其載入的文檔的源铐拐,因?yàn)檫@些偽協(xié)議的URL并沒(méi)有明確地包含有關(guān)服務(wù)器的源的信息徘键。當(dāng)調(diào)用window.open()打開一個(gè)about:blank頁(yè)面時(shí),若該頁(yè)面有代碼遍蟋,則會(huì)繼承創(chuàng)建該頁(yè)面的代碼的源吹害。而data:URLs則會(huì)重新得到一個(gè)新的空的安全的上下文,不會(huì)繼承源

注意:在Gecko 6.0之前虚青,如果用戶在地址欄中輸入 data URLs它呀,data URLs 將繼承當(dāng)前瀏覽器窗口中網(wǎng)頁(yè)的安全上下文

四、IE是例外

在同源策略中棒厘,Internet Explorer有兩點(diǎn)不同

  • 授信范圍(Trust Zones):兩個(gè)相互之間高度互信的域名纵穿,如公司域名 (corporate domains),不遵守同源策略的限制奢人。
  • 端口:未將端口號(hào)加入到同源策略的組成部分之中谓媒,因此 http://abc.com:81/index.htmlhttp://abc.com/index.html 屬于同源并且不受任何限制。

五何乎、修改源

頁(yè)面可以改變本身的源句惯,但是會(huì)有一些限制。腳本可以將 document.domain設(shè)置為當(dāng)前域或者當(dāng)前域的超級(jí)域支救,該較短的域會(huì)用于后續(xù)源檢查抢野。

假如當(dāng)前頁(yè)面http://abc.jjp.com/index.html文檔中執(zhí)行如下腳本,將當(dāng)前域設(shè)置當(dāng)前域的超級(jí)域

document.domain = 'jjp.com'

設(shè)置完之后搂妻,該頁(yè)面會(huì)通過(guò)http://jjp.com/page.html的同源檢查蒙保,同時(shí)abc.jjp.com不能設(shè)置為efg.jjp.com,因?yàn)?code>efg.jjp.com不是abc.jjp.com的超級(jí)域

如果存在端口號(hào)不一致欲主,想通過(guò)document.domain設(shè)置的方式來(lái)通過(guò)同源檢查的話需要雙方都進(jìn)行設(shè)置。因?yàn)樵O(shè)置document.domain會(huì)導(dǎo)致端口號(hào)被重寫為null逝嚎。如果jjp.com:8080想要與jjp.com通信扁瓢,把jjp.com:8080頁(yè)面的document.domain設(shè)置為jjp.com時(shí)端口號(hào)會(huì)被重寫為null,而原來(lái)的jjp.com的端口號(hào)為80补君,則還是不能夠通過(guò)同源檢測(cè)引几,需要雙方同時(shí)設(shè)置document.domain讓雙方端口號(hào)都為null。

注意:document.domain能夠讓子域訪問(wèn)其父域,但是需要同時(shí)將子域和父域的document.domain設(shè)置為相同的值伟桅。這是必要的敞掘,即使是簡(jiǎn)單的將父域設(shè)置為其原來(lái)的值。不這么做的話可能導(dǎo)致權(quán)限錯(cuò)誤

六楣铁、不同源之間的交互

同源策略控制了不同源的交互玖雁,主要有三類交互

  • 跨域?qū)?/strong>:通常允許,比如鏈接盖腕、重定向表單提交(因?yàn)楸韱翁峤徊恍枰答仈?shù)據(jù))
  • 跨域資源嵌入:通常允許赫冬,下面會(huì)給出跨域資源嵌入的例子
  • 跨域讀:通常不允許,比如在使用XMLHttpRequest的時(shí)候會(huì)發(fā)生跨域問(wèn)題溃列,不過(guò)通過(guò)某些方法仍可以進(jìn)行跨域讀

跨域資源嵌入的例子

  • <script src="..."></script>標(biāo)簽嵌入外域的腳本劲厌,且該腳本的錯(cuò)誤不能在本源中捕獲
  • <link rel= "stylesheet" href="...">標(biāo)簽嵌入外域的css文件,由于CSS的松散的語(yǔ)法規(guī)則听隐,CSS的跨域需要一個(gè)設(shè)置正確的Content-Type 消息頭补鼻,不同瀏覽器有不同的限制。
  • <img>嵌入外域的圖片
  • <video>和<audio>標(biāo)簽嵌入外域的多媒體資源
  • <object>和<embed>的插件
  • @font-face引入的字體雅任,一些瀏覽器允許引入外域字體风范,一些瀏覽器則不允許
  • <iframe> 載入的任何資源,站點(diǎn)可以使用X-Frame-Options消息頭來(lái)阻止這種形式的跨域交互

七、如何避免跨域訪問(wèn)

  • 避免跨域?qū)?/strong>:在發(fā)起寫請(qǐng)求中攜帶一個(gè)隱藏的token,然后服務(wù)器端對(duì)這個(gè)token進(jìn)行驗(yàn)證可很,多用來(lái)防范CSRF攻擊
  • 避免跨域讀:要保證返回給客戶端的資源是不可嵌入的哗戈,不可以是上面列出的允許跨域資源嵌入的標(biāo)簽
  • 避免跨域資源嵌入:需要確保html文檔中沒(méi)有上面列出的允許跨域資源嵌入的標(biāo)簽

八、跨源文檔API的訪問(wèn)

javascript的api中因痛,允許文檔間互相引用,如 iframe.contentWindowwindow.parent猪腕, window.openwindow.opener,這些api可以拿到其他文檔的對(duì)象的引用钦勘,但是當(dāng)兩個(gè)文檔不同源時(shí)陋葡,對(duì)該對(duì)象(如WindowLocation)的訪問(wèn)就會(huì)有所限制彻采。如果想要兩個(gè)不同源的窗口進(jìn)一步交流可以使用window.postMessage

九、跨源數(shù)據(jù)存儲(chǔ)訪問(wèn)

localStorageIndexedDB等數(shù)據(jù)存儲(chǔ)會(huì)以源進(jìn)行分割虎囚,每個(gè)源擁有自己獨(dú)立的存儲(chǔ)空間,一個(gè)源的js腳本不能對(duì)屬于其他源的數(shù)據(jù)進(jìn)行讀寫操作

cookies同樣只有同源網(wǎng)頁(yè)才能共享留攒,設(shè)置其domain剪侮、path瓣俯、secure彩匕、HttpOnly屬性可以來(lái)限定其訪問(wèn)性

屬性 作用
domain 指定cookies對(duì)哪個(gè)域有效掸犬,cookies只會(huì)發(fā)向該域湾碎,默認(rèn)值是設(shè)置cookie的那個(gè)域
path 表示相對(duì)于domain的路徑递惋,只有在該路徑下才能拿到cookies,默認(rèn)值為/
secure 設(shè)置了該屬性或者設(shè)置了'secure=true'表示只能在 HTTPS 連接中傳遞cookies
HttpOnly 設(shè)置了該屬性或這設(shè)置了'HttpOnly=true'表示js腳本不能讀取到cookie信息

十、實(shí)現(xiàn)跨域讀取的方案

1.XMLHttpRequest的跨域
方案:
  1.JSONP
  2.CORS
  3.WebSocket
  4.代理

方案1:JSONP

只能用于Get請(qǐng)求卵迂,老式瀏覽器都支持。在網(wǎng)頁(yè)中創(chuàng)建一個(gè)<script>標(biāo)簽,src為請(qǐng)求的url宝当,請(qǐng)求的查詢字符串有一個(gè)callback參數(shù)庆揩,用來(lái)指定回調(diào)函數(shù)的名稱,回調(diào)函數(shù)在js腳本中聲明好订晌。當(dāng)服務(wù)器收到請(qǐng)求后蚌吸,返回一句js腳本锈拨,內(nèi)容是將json數(shù)據(jù)作為參數(shù)傳入回調(diào)函數(shù)并調(diào)用該函數(shù)羹唠。

實(shí)例:

前端:
var jsonp = {
    exec: function() {
        var script = document.getElementById('jsonp');
        if(script) {
            script.parentElement.removeChild(script);
        }
        //創(chuàng)建<script>標(biāo)簽
        script = document.createElement('script');
        script.id = 'jsonp';
        //返回js腳本:
        //jsonp.jsonpcallback({"code":1000,"data":{"username":"carl","userAge":20,"userSex":"男"}})
        script.src = 'http://localhost:8080/getusermsg?callback=jsonp.jsonpcallback';
        document.head.appendChild(script);        
    },
    //返回js腳本時(shí)會(huì)調(diào)用該函數(shù)
    jsonpcallback: function (userdata) { 
        alert('姓名:' + userdata.data.username);
        alert('年齡:'+ userdata.data.userAge);
        alert('性別:' + userdata.data.userSex);
    }
 }
 $('#btn1').click(jsonp.exec);

服務(wù)端:
function getusermsg(req, res, next) {
    if(req.url.match(api.getusermsg)) {
        var queryJson = queryParse(req.url.split('?')[1]); 
        var fb = {code: 1000, data: {username: 'carl', userAge: 20, userSex: '男'}};
        //查詢字符串中有callback參數(shù)
        if(queryJson.callback) {
            res.writeHead(200);
            //返回調(diào)用回調(diào)函數(shù)的字符串喊衫,前端以js腳本來(lái)解析并執(zhí)行
            res.write(queryJson.callback + '(' + JSON.stringify(fb) + ')');
        }else {
            res.setHeader('Access-Control-Allow-Origin', '*');
            res.writeHead(200);
            res.write(JSON.stringify(fb));
        }
    }
    next();
}

同樣也可以用jquery來(lái)發(fā)起jsonp請(qǐng)求族购,其原理也是跟上面一樣,只是對(duì)其進(jìn)行了一些封裝寝杖,調(diào)用起來(lái)更方便违施。因?yàn)槭墙柚?code><script>標(biāo)簽的src屬性,JSONP只能發(fā)GET請(qǐng)求

方案2.CORS

CORS是跨域資源分享的縮寫瑟幕,能夠徹底解決Ajax的跨域問(wèn)題磕蒲,同時(shí)允許任意類型的請(qǐng)求留潦,需要服務(wù)器響應(yīng)頭中增加下面一種或幾種

//*表示允許任意源的訪問(wèn),也可以指定特定的源
1.Access-Control-Allow-Origin:*   
//表示跨域訪問(wèn)時(shí)帶上cookie辣往,需同時(shí)在ajax請(qǐng)求中設(shè)置`withCredentials: true`兔院,
2.Access-Control-Allow-Credentials: true
//預(yù)檢請(qǐng)求后響應(yīng)的必須字段,返回所有支持的方法站削,而不單是瀏覽器請(qǐng)求的那個(gè)方
//法坊萝。這是為了避免多次"預(yù)檢"請(qǐng)求
3.Access-Control-Allow-Methods: GET, POST, PUT
//預(yù)檢請(qǐng)求后響應(yīng)的必須字段,放入預(yù)檢請(qǐng)求時(shí)請(qǐng)求所帶的頭
4.Access-Control-Allow-Headers:Content-Type
//允許瀏覽器在指定時(shí)間內(nèi)许起,無(wú)需再發(fā)送預(yù)檢請(qǐng)求進(jìn)行協(xié)商十偶,直接用本次協(xié)商結(jié)果即可
5.Access-Control-Max-Age: 1728000

CORS請(qǐng)求分為簡(jiǎn)單請(qǐng)求(HEAD、GET园细、POST)非簡(jiǎn)單請(qǐng)求(PUT或DELETE或Content-Type為application)
非簡(jiǎn)單請(qǐng)求會(huì)向發(fā)一個(gè)預(yù)檢請(qǐng)求(preflight)惦积,請(qǐng)求類型為OPTION,收到預(yù)檢請(qǐng)求的響應(yīng)后再發(fā)送真正的請(qǐng)求珊肃,這個(gè)時(shí)候的請(qǐng)求與簡(jiǎn)單請(qǐng)求無(wú)異荣刑。

簡(jiǎn)單地說(shuō)下CORS請(qǐng)求會(huì)攜帶的頭信息

//必要請(qǐng)求頭,表示當(dāng)前源伦乔,相應(yīng)的預(yù)檢響應(yīng)需要返回Access-Control-Allow-Origin
1.Origin
//預(yù)檢時(shí)會(huì)帶上的頭厉亏,表示真正請(qǐng)求的方法,相應(yīng)的預(yù)檢響應(yīng)需要返回Access-Control-Allow-Method
2.Access-Control-Request-Method
//預(yù)檢時(shí)會(huì)帶上的頭烈和,表示真正請(qǐng)求會(huì)額外發(fā)送的頭信息爱只,相應(yīng)的預(yù)檢響應(yīng)需要返回Access-Control-Allow-Headers
3.Access-Control-Request-Headers

示例:

//1.簡(jiǎn)單請(qǐng)求
//前端
var cors = function() {
    $.ajax(
        {
            url: 'http://localhost:8080/getusermsg',
            type: 'GET',
            dataType: 'json',
            success: function(userdata) {
                alert('姓名:' + userdata.data.username);
                alert('年齡:'+ userdata.data.userAge);
                alert('性別:' + userdata.data.userSex);
            },
            error: function(error) {
                alert(JSON.stringify(error));
            }
        }
    )
}
//服務(wù)端
function getusermsg(req, res, next) {
    if(req.url.match(api.getusermsg)) {
        var queryJson = queryParse(req.url.split('?')[1]); 
        var fb = {code: 1000, data: {username: 'carl', userAge: 20, userSex: '男'}};
        if(queryJson.callback) {
            res.writeHead(200);
            res.write(queryJson.callback + '(' + JSON.stringify(fb) + ')');
        }else {
            //允許任意源訪問(wèn)
            res.setHeader('Access-Control-Allow-Origin', '*');
            res.writeHead(200);
            res.write(JSON.stringify(fb));
        }
    }
    next();
}

//2.非簡(jiǎn)單請(qǐng)求
//前端
var postUser = function() {
    $.ajax({
        url: 'http://localhost:8080/postusermsg',
        type: 'POST',
        //發(fā)送json數(shù)據(jù)觸發(fā)預(yù)檢preflight,option請(qǐng)求
        contentType: 'application/json',  
        data: {username: 'jjp', userAge: 22, userSex: '男'},
        dataType: 'json',
        success: function(data) {
            if(data.code === 1000) {
                alert('添加用戶成功')
            }
        },
        error: function(err) {
            alert(JSON.stringify(err));
        }
    })
}

//服務(wù)端
function postusermsg(req, res, next) {
    if(req.url.match(api.postusermsg)) {
        var body = '';
        req.on('data', function(chunk){    
            body += chunk;
        });
        req.on('end', function(){    
            var queryJson = queryParse(body);
            console.log(queryJson);
            //針對(duì)預(yù)檢請(qǐng)求發(fā)送的頭為響應(yīng)設(shè)置相對(duì)應(yīng)的頭
            res.setHeader('Access-Control-Allow-Origin', '*');
            res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
            res.setHeader('Access-Control-Allow-Method', 'GET,POST,PUT');
            res.writeHead(200);
            res.write(JSON.stringify({code:1000, data:{}}));
            next();
        });
    }else {
        next();
    }
}

方案3.WebSocket

WebSocket是一種新的通信協(xié)議招刹,能夠在一個(gè)持久連接上提供全雙工恬试、雙向通信。使用url模式也略有不同疯暑。未加密連接使用ws://训柴,加密連接使用wss://,最重要的一點(diǎn)是該協(xié)議不實(shí)行同源策略妇拯。服務(wù)器需要自己確定請(qǐng)求源是否在白名單內(nèi)幻馁,從而過(guò)濾惡意的請(qǐng)求。

方案4.代理

1.正向代理:需要借助同源的代理服務(wù)器越锈,瀏覽器先將請(qǐng)求發(fā)送給代理服務(wù)器仗嗦,代理服務(wù)器接收請(qǐng)求并其轉(zhuǎn)發(fā)給目標(biāo)數(shù)據(jù)服務(wù)器,由于不同源的兩個(gè)服務(wù)器的交互不遵循同源策略甘凭,所以代理服務(wù)器可以接收到目標(biāo)數(shù)據(jù)服務(wù)器的響應(yīng)數(shù)據(jù)稀拐,再將響應(yīng)數(shù)據(jù)發(fā)送回瀏覽器

2.反向代理:通常可以用Nginx反向代理來(lái)實(shí)現(xiàn)丹弱,也是利用了服務(wù)端之間的資源交互不會(huì)有跨域限制的原理德撬。假如現(xiàn)在有
domainAhttp://jjp.com:3000铲咨,部署了請(qǐng)求頁(yè)面
domainBhttp://jjp.com:8080,部署了nginx服務(wù)器
domainChttp://jjp.com:6600砰逻,部署了資源服務(wù)器

瀏覽器獲取了domainA的頁(yè)面鸣驱,然后用ajaxdomainC請(qǐng)求數(shù)據(jù),必然會(huì)發(fā)生跨域蝠咆。所以domainA可以讓nginx做反向代理服務(wù)器,讓nginx服務(wù)器假扮domainA北滥,此時(shí)瀏覽器請(qǐng)求domainB時(shí)會(huì)得到原先部署在domainA上的頁(yè)面刚操。瀏覽器想請(qǐng)求domainC的資源時(shí),直接向domainB發(fā)請(qǐng)求即可再芋,nginx服務(wù)器會(huì)攔截瀏覽器的請(qǐng)求菊霜,重寫為向domainC請(qǐng)求,再轉(zhuǎn)發(fā)該請(qǐng)求济赎,nginx拿到資源后返回給瀏覽器

2.Cookie的跨域

同源的頁(yè)面才可以共享cookie鉴逞,但是如果兩個(gè)源的一級(jí)域名相同,二級(jí)域名不同司训,瀏覽器可以通過(guò)設(shè)置document.domain來(lái)共享cookie构捡,比如有

domainA:http://gg.jjp.com/index.html
domainB:http://bb.jjp.com/index.html

現(xiàn)在想讓domainAdomainB能互相訪問(wèn)對(duì)方的cookie,可以雙方都設(shè)置document.domainjjp.com壳猜,domainA則能夠訪問(wèn)到domainB設(shè)置的cookie勾徽,domainB也能訪問(wèn)到domainA設(shè)置的cookie.

3.跨窗口的跨域通信

iframe窗口和window.open打開的窗口若與父窗口不是同源的,都無(wú)法與創(chuàng)建它們的父窗口通信统扳,無(wú)法互相訪問(wèn)對(duì)方的document對(duì)象喘帚。如果兩個(gè)窗口一級(jí)域名相同,二級(jí)域名不同咒钟,可以通過(guò)設(shè)置document.domain解決吹由。
但是對(duì)于完全不同源的窗口,想要進(jìn)行通信朱嘴,可以通過(guò)下面的方法:

1.片段識(shí)別符
2.window.name
3.window.postMessage

方案1.片段識(shí)別符

地址欄中url#后面的內(nèi)容變化是不會(huì)引起頁(yè)面的刷新的倾鲫,這部分內(nèi)容就是片段識(shí)別符,當(dāng)片段識(shí)別符內(nèi)容變化時(shí)腕够,會(huì)觸發(fā)hashchange事件级乍。

因此發(fā)信息的窗口可以把信息寫入接收信息窗口的片段標(biāo)識(shí)符中,接收信息窗口監(jiān)聽hashchange事件來(lái)取得自己的片段標(biāo)識(shí)符帚湘,從而來(lái)達(dá)成通信的目的玫荣。

方案2.window.name

window.name值在不同的頁(yè)面(甚至不同域名)加載后依舊存在,并且值最大可以達(dá)到2MB大诸。

示例:窗口A和窗口B不同源捅厂,現(xiàn)在A想拿到窗口B的消息贯卦,可以借助window.name 以及 iframe實(shí)現(xiàn)跨域通信

步驟:
1.窗口A在頁(yè)面中動(dòng)態(tài)添加一個(gè)iframe,將其src置為窗口B頁(yè)面地址
2.iframe加載了窗口B的頁(yè)面焙贷,窗口B將要發(fā)送的消息寫入window.name中
3.由于窗口A與iframe處于不同域撵割,因?yàn)橥床呗裕翱贏不能訪問(wèn)iframe的window.name
4.此時(shí)再讓iframe加載一個(gè)與窗口A同源的頁(yè)面辙芍,使窗口A與iframe屬于同域
5.窗口A讀取iframe的window.name啡彬,至此接收到窗口B發(fā)送的消息,完成通信

方案3.window.postMessage

window.postMessageHTML5引入的一個(gè)新的api故硅,允許兩個(gè)窗口通信庶灿,不論是否兩個(gè)窗口是否同源

示例:

//發(fā)送信息的窗口:http://jjp.com
var sonWin = window.open('https://www.baidu.com','百度');
//參數(shù):要發(fā)送的信息、接受信息的窗口的源
sonWin.postMessage('你好吃衅,百度', 'https://www.baidu.com');

//接收信息的窗口:https://www.baidu.com
//監(jiān)聽postMessage事件
window.addEventListener('message', function(event) {
  //event.source:發(fā)送消息的窗口
  //event.origin: 發(fā)送消息的網(wǎng)址
  //event.data: 消息內(nèi)容
  if(event.origin === 'http://jjp.com') {
    event.source.postMessage('Got it', event.origin);
    console.log(event.data)
  }
});
4.跨源數(shù)據(jù)存儲(chǔ)

通過(guò)window.postMessage往踢,能夠?qū)崿F(xiàn)讀寫其他窗口的localStorageIndexDB
在用window.postMessage實(shí)現(xiàn)窗口間的通信的基礎(chǔ)上進(jìn)行

  • 寫:接收其他窗口的消息時(shí)徘层,將消息作為值其存入
  • 讀:接受其他窗口的消息時(shí)峻呕,將消息作為鍵值取出值,并將值通過(guò)postMessage發(fā)送給其他窗口

參考文章

瀏覽器的同源策略
瀏覽器的同源策略及其規(guī)避辦法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末趣效,一起剝皮案震驚了整個(gè)濱河市瘦癌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌英支,老刑警劉巖佩憾,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異干花,居然都是意外死亡妄帘,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門池凄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)抡驼,“玉大人,你說(shuō)我怎么就攤上這事肿仑≈旅耍” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵尤慰,是天一觀的道長(zhǎng)馏锡。 經(jīng)常有香客問(wèn)我,道長(zhǎng)伟端,這世上最難降的妖魔是什么杯道? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮责蝠,結(jié)果婚禮上党巾,老公的妹妹穿的比我還像新娘萎庭。我一直安慰自己,他們只是感情好齿拂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布驳规。 她就那樣靜靜地躺著,像睡著了一般署海。 火紅的嫁衣襯著肌膚如雪吗购。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天叹侄,我揣著相機(jī)與錄音巩搏,去河邊找鬼。 笑死趾代,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丰辣。 我是一名探鬼主播撒强,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼笙什!你這毒婦竟也來(lái)了飘哨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤琐凭,失蹤者是張志新(化名)和其女友劉穎芽隆,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體统屈,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胚吁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了愁憔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腕扶。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖吨掌,靈堂內(nèi)的尸體忽然破棺而出半抱,到底是詐尸還是另有隱情,我是刑警寧澤膜宋,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布窿侈,位于F島的核電站,受9級(jí)特大地震影響秋茫,放射性物質(zhì)發(fā)生泄漏史简。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一学辱、第九天 我趴在偏房一處隱蔽的房頂上張望乘瓤。 院中可真熱鬧环形,春花似錦、人聲如沸衙傀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)统抬。三九已至火本,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間聪建,已是汗流浹背钙畔。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留金麸,地道東北人擎析。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像挥下,于是被迫代替她去往敵國(guó)和親揍魂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

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