File詳解

本文轉(zhuǎn)載自博客園博主小火柴的藍(lán)色理想绽诚。

Blob

Blob是計算機(jī)界通用術(shù)語之一件甥,全稱寫作:BLOB(binary large object)藏研,表示二進(jìn)制大對象漠嵌。MySql/Oracle數(shù)據(jù)庫中,就有一種Blob類型盖呼,專門存放二進(jìn)制數(shù)據(jù)儒鹿。在JS中,Blob通常表示二進(jìn)制數(shù)據(jù)几晤,不過它們不一定非得是大量數(shù)據(jù)约炎,Blob也可以表示一個小型文本文件的內(nèi)容。

構(gòu)造函數(shù) Blob(array[, options])

Blob()構(gòu)造函數(shù)返回一個新的Blob對象蟹瘾,blob的內(nèi)容由參數(shù)數(shù)組中給出的值的串聯(lián)組成圾浅。
參數(shù)array是一個由ArrayBufferArrayBufferView憾朴、Blob狸捕、DOMString等對象構(gòu)成的Array,或者其他類似對象的混合體众雷,它將會被放進(jìn)Blob灸拍。

參數(shù)options是一個可選項,它可能會指定如下兩種屬性:
  1砾省、類型鸡岗,默認(rèn)值為"",它代表了將會被放入到blob中的數(shù)組內(nèi)容的MIME類型编兄。
  2轩性、結(jié)束符,默認(rèn)值為"transparent"狠鸳,它代表包含行結(jié)束符\n的字符串如何被輸出揣苏。它是以下兩個值中的一個:"native",代表行結(jié)束符會被更改為適合宿主操作系統(tǒng)文件系統(tǒng)的慣例碰煌,或者"transparent"舒岸,代表會保持blob中保存的結(jié)束符不變。

var aFileParts = ['<a id="a"><b id="b">hey!</b></a>']; 
var oMyBlob = new Blob(aFileParts, {type : 'text/html'}); 
console.log(oMyBlob);//Blob {size: 32, type: "text/html"}
屬性和方法

Blob是不透明的芦圾,能對它們進(jìn)行直接操作的就只有獲取它們的大小(以字節(jié)為單位)蛾派、MIME類型以及將它們分割成更小的Blob。
Blob.size(只讀):返回Blob對象中所包含數(shù)據(jù)的大小(字節(jié))。
Blob.type(只讀):一個字符串洪乍,表明該Blob對象所包含數(shù)據(jù)的MIME類型眯杏。如果類型未知,則該值為空字符串壳澳。

var myBlob = new Blob([1,2,3],{type:'text/plain'});
console.log(myBlob);//Blob {size: 3, type: "text/plain"}
console.log(myBlob.size);//3
console.log(myBlob.type);//'text/plain'
Blob.slice([start[, end[, contentType]]])

slice()方法返回一個新的Blob對象岂贩,包含了源Blob對象中指定范圍內(nèi)的數(shù)據(jù)。

var subblob = blob.slice(0,1024, "text/plain");//Blob中前1KB視為文本
var last = blob.slice(blob.size-1024, 1024);//Blob中最后1KB視為無類型

Web瀏覽器可以將Blob存儲到內(nèi)存中或者磁盤上巷波,Blob可以表示非常大的數(shù)據(jù)塊(比如視頻文件)萎津,如果事先不用slice()方法將它們分割成為小數(shù)據(jù)塊的話,無法存儲在主內(nèi)存中抹镊。正是因為Blob可以表示非常大的數(shù)據(jù)塊锉屈,并且它可能需要磁盤的訪問權(quán)限,所以使用它們的API是異步的(在Worker線程中有提供相應(yīng)的同步版本)垮耳。

文件作為Blob

在使用Blob之前颈渊,首先必須要獲取Blob。其中一種方式就是把文件作為Blob终佛。
在支持本地文件訪問的瀏覽器中俊嗽,<input type="file">元素上的files屬性則是一個FileList對象。該對象是一個類數(shù)組對象铃彰,其元素要么是0绍豁,要么是用戶選擇的多個File對象。一個File對象就是一個Blob牙捉,除此之外妹田,還多了name和lastModifiedDate屬性。

<script>
//輸出選中的文件列表相關(guān)的信息
function fileinfo(files) {
    for(var i = 0; i < files.length; i++) {//files是一個類數(shù)組對象
        var f = files[i];
        //a.txt 86 text/plain Mon Sep 19 2016 11:07:43 GMT+0800 (中國標(biāo)準(zhǔn)時間)
        console.log(f.name,    //只是名字:沒有路徑
                    f.size, f.type,    //size和type是Blob的屬性
                    f.lastModifiedDate);    //修改時間
    }
}
</script>
<input type="file"  onchange="fileinfo(this.files)"/>
下載Blob

在實際Web應(yīng)用中鹃共,Blob更多是圖片二進(jìn)制形式的上傳與下載鬼佣,雖然其可以實現(xiàn)幾乎任意文件的二進(jìn)制傳輸。
第二種獲取Blob的形式是通過XHR下載Blob霜浴。

var xhr = new XMLHttpRequest();    //創(chuàng)建一個新的XHR對象 
xhr.open('GET','p5.gif');            //指定要獲取內(nèi)容的URL
xhr.responseType = 'blob';        //以Blob的形式
xhr.onload = function(){         //onload 比onreadystatechange更容易
    //Blob {size: 944, type: "image/gif"} 
    console.log(xhr.response);  //response返回的就是Blob對象    
}                                
xhr.send(null);                    //發(fā)送請求
Blob URL

前面介紹了如何獲取或者創(chuàng)建Blob晶衷。下面來介紹如何對獲取或者創(chuàng)建的Blob進(jìn)行操作。其中最簡單的就是可以創(chuàng)建一個URL來指向該Blob阴孟。隨后晌纫,可以以一般的URL形式在任何地方使用該URL:在D0M中、在樣式表中永丝、甚至可以作為XMLHttpRequest的目標(biāo)锹漱。

objectURL = URL.createObjectURL(blob);
var xhr = new XMLHttpRequest();     
xhr.open('GET','test/p5.gif');    
xhr.responseType = 'blob';    
xhr.onload = function(){ 
    //blob:http://127.0.0.1/539ae798-70db-44db-b216-fc932b358285
    console.log(URL.createObjectURL(xhr.response));
}    
xhr.send(null);

[注意]blob://URLdata://URL是不同的,data://URL會對內(nèi)容進(jìn)行編碼慕嚷。blob://URL只是對瀏覽器存儲在內(nèi)存中或者磁盤上的Blob的一個簡單引用哥牍。

file URL

blob://URLfile://URL也是不同的毕泌,file://URL直接指向本地文件系統(tǒng)中的一個文件,僅暴露了文件的路徑嗅辣、瀏覽目錄的許可等撼泛,除此之外任何內(nèi)容都會帶來安全問題的。
Blob URL和創(chuàng)建它們的腳本擁有同樣的源澡谭。這使得它們比file://URL更加靈活愿题,由于file://URL是非同源的,因此要在Web應(yīng)用中使用它們相對比較麻煩蛙奖。Blob://URL只有在同源的文檔中才是有效的潘酗。比如,如果將一個Blob URL通過postMessage()傳遞給一個非同源窗口雁仲,則該URL對于該窗口來說是沒有任何意義的崎脉。
Blob URL并不是永久有效的。一旦用戶關(guān)閉了或者離開了包含創(chuàng)建Blob URL腳本的文檔伯顶,該Blob URL就失效了。比如骆膝,將Blob URL保存到本地存儲器中祭衩,然后當(dāng)用戶開始一個新的Web應(yīng)用會話的時再使用它,是不可能的阅签。

URL.revokeObjectURL()

URL.createObjectURL()創(chuàng)建的已經(jīng)存在的URL對象掐暮。當(dāng)結(jié)束使用某個URL對象時,應(yīng)該通過調(diào)用這個方法來讓瀏覽器知道不再需要保持這個文件的引用了政钟。

window.URL.revokeObjectURL(objectURL);

參數(shù)objectURL是一個DOMString路克,表示通過調(diào)用URL.createObjectURL()方法產(chǎn)生的URL對象。
之所以提供這樣的方式养交,是因為這和內(nèi)存管理問題有關(guān)精算。一旦使用之后,Blob就不再需要了碎连,應(yīng)當(dāng)回收它灰羽。

文件File

不能直接訪問用戶計算機(jī)中的文件,一直都是Web應(yīng)用開發(fā)中的一大障礙鱼辙。2000年以前廉嚼,處理文件的唯一方式就是在表單中加入<input type="file">字段,僅此而已倒戏。FileAPI(文件API)的宗旨是為Web開發(fā)人員提供一種安全的方式怠噪,以便在客戶端訪問用戶計算機(jī)中的文件,并更好地對這些文件執(zhí)行操作杜跷。

File API在表單中的文件輸入字段的基礎(chǔ)上傍念,又添加了一些直接訪問文件信息的接口矫夷。HTML5在DOM中為文件輸入元素添加了一個files集合。在通過文件輸入字段選擇了一或多個文件時捂寿,files集合中將包含一組File對象口四,每個File對象對應(yīng)著一個文件。每個File對象都有下列只讀屬性秦陋。

name:本地文件系統(tǒng)中的文件名
size:文件的字節(jié)大小
type:字符串蔓彩,文件的MIME類型
lastModifiedDate:字符串,文件上一次被修改的時間

通過偵聽change事件并讀取files集合就可以知道選擇的每個文件的信息驳概。

<input type="file" id="file1">
<div id="result"></div>
<script>
file1.onchange = function(){
    var data = file1.files[0];
    result.innerHTML = '類型:' + data.type  + '<br>大谐嘟馈:' + data.size + '(字節(jié))<br>名稱:' + data.name + '<br>修改時間:' + data.lastModifiedDate;
}
</script>
隱藏文件input

現(xiàn)代瀏覽器支持隱藏掉默認(rèn)的的文件輸入框<input>元素,使用自定義的界面來充當(dāng)打開文件選擇對話框的按鈕顺又。實現(xiàn)起來很簡單更卒,只需要使用樣式display:none把原本的文件輸入框隱藏掉,然后在需要的時候調(diào)用它的click()方法就行了稚照。

<input type="file" id="file1" style="display:none">
<button id="btn">按鈕</button>
<div id="result"></div>
<script>
btn.onclick = function(){
    file1.click();
}
file1.onchange = function(){
    result.innerHTML = file1.files[0].name;
}
</script>
FileReader

File API的功能還不止于此蹂空,通過它提供的FileReader類型甚至還可以讀取文件中的數(shù)據(jù)。

構(gòu)造函數(shù)

使用FileReader()構(gòu)造函數(shù)來創(chuàng)建一個FileReader對象

var reader = new FileReader();
屬性

error:表示在讀取文件時發(fā)生的錯誤(只讀)
readyState:表明FileReader對象的當(dāng)前狀態(tài)果录,值為狀態(tài)常量中的一個(只讀)
  狀態(tài)常量有以下三個

常量名      值    描述
EMPTY      0    還沒有加載任何數(shù)據(jù)
LOADING    1    數(shù)據(jù)正在被加載
DONE       2    已完成全部的讀取請求

result:表示讀取到的文件內(nèi)容上枕,這個屬性只在讀取操作完成之后才有效,并且數(shù)據(jù)的格式取決于讀取操作是由哪個方法發(fā)起的(只讀)弱恒。

方法

FileReader類型實現(xiàn)的是一種異步文件讀取機(jī)制辨萍。可以把FileReader想象成XMLHttpRequest返弹,區(qū)別只是它讀取的是文件系統(tǒng)锈玉,而不是遠(yuǎn)程服務(wù)器。為了讀取文件中的數(shù)據(jù)义起,F(xiàn)ileReader提供了如下幾個方法拉背。
abort():中止該讀取操作。
readAsText(file或Blob,encoding):以純文本形式讀取File或Blob對象的內(nèi)容默终,將讀取到的文本保存在result屬性中去团。第二個參數(shù)(可選)用于指定編碼類型,默認(rèn)為UTF-8穷蛹。
readAsDataURL(file或Blob):讀取File或Blob對象的內(nèi)容土陪,并將文件以數(shù)據(jù)URI(進(jìn)行Base64編碼)的形式保存在result屬性中。
readAsBinaryString(file或Blob):讀取File或Blob對象的內(nèi)容肴熏,并將一個字符串保存在result屬性中鬼雀,字符串中的每個字符表示一字節(jié)。
readAsArrayBuffer(file或Blob):讀取File或Blob對象的內(nèi)容蛙吏,并將一個包含文件內(nèi)容的ArrayBuffer保存在result屬性中源哩。
這些讀取文件的方法為靈活地處理文件數(shù)據(jù)提供了極大便利鞋吉。例如,可以讀取圖像文件并將其保存為數(shù)據(jù)URI励烦,以便將其顯示給用戶谓着,或者為了解析方便,可以將文件讀取為文本形式坛掠。

事件

由于讀取過程是異步的赊锚,因此FileReader也提供了幾個事件
onabort:當(dāng)讀取操作被中止時調(diào)用
onerror:當(dāng)讀取操作發(fā)生錯誤時調(diào)用
onload:當(dāng)讀取操作成功完成時調(diào)用
onloadend:當(dāng)讀取操作完成時調(diào)用,不管是成功還是失敗屉栓。該處理程序在onload或者onerror之后調(diào)用
onloadstart:當(dāng)讀取操作將要開始之前調(diào)用
onprogress:在讀取數(shù)據(jù)過程中周期性調(diào)用
在正常情況下舷蒲,讀取文件時,首先觸發(fā)loadstart事件友多,此時的readyState為1牲平,result為空。
接著域滥,每過50ms左右纵柿,就會觸發(fā)一次progress事件,通過事件對象可以獲得與XHR的progress事件相同的信息(屬性):lengthComputable启绰、loaded和total昂儒。另外,盡管可能沒有包含全部數(shù)據(jù)酬土,但每次progress事件中都可以通過FileReaderresult屬性讀取到文件內(nèi)容,readyState仍然是1格带。
  當(dāng)文件讀取完成時撤缴,觸發(fā)load事件,此時的readyState為2叽唱,result為文件內(nèi)容屈呕;如果發(fā)生了error事件,就不會發(fā)生load事件棺亭。

<input type="file" id="file1">
<div id="result"></div>
<script>
/*
[loadstart]readyState:1;result:
[progress]readyState:1;result:h3{color: #F44336;}
[load]readyState:2;result:h3{color: #F44336;}
[loadend]readyState:2;result:h3{color: #F44336;}
*/
file1.onchange = function(){
    var reader = new FileReader();
    reader.readAsText(file1.files[0]);
    reader.onloadstart = function(e){
        console.log('[loadstart]readyState:' + reader.readyState + ';result:' + reader.result);
    }
    reader.onload = function(e){
        console.log('[load]readyState:' + reader.readyState + ';result:' + reader.result);
    }
    reader.onloadend = function(e){
        console.log('[loadend]readyState:' + reader.readyState + ';result:' + reader.result);
    }
    reader.onprogress = function(e){
        console.log('[progress]readyState:' + reader.readyState + ';result:' + reader.result);
    }
}
</script>

在觸發(fā)load虎眨、errorabort事件后,會觸發(fā)另一個事件loadend镶摘。loadend事件發(fā)生就意味著已經(jīng)讀取完整個文件嗽桩,或者讀取時發(fā)生了錯誤,或者讀取過程被中斷凄敢。

縮略圖

使用FileReader對象的readAsDataURL()方法完成對文件的讀取碌冶,再通過File對象的type屬性篩選出圖片。

<img id="uploadPreview" style="width: 100px; height: 100px;" src="data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%3F%3E%0A%3Csvg%20width%3D%22153%22%20height%3D%22153%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%0A%20%3Cg%3E%0A%20%20%3Ctitle%3ENo%20image%3C/title%3E%0A%20%20%3Crect%20id%3D%22externRect%22%20height%3D%22150%22%20width%3D%22150%22%20y%3D%221.5%22%20x%3D%221.500024%22%20stroke-width%3D%223%22%20stroke%3D%22%23666666%22%20fill%3D%22%23e1e1e1%22/%3E%0A%20%20%3Ctext%20transform%3D%22matrix%286.66667%2C%200%2C%200%2C%206.66667%2C%20-960.5%2C%20-1099.33%29%22%20xml%3Aspace%3D%22preserve%22%20text-anchor%3D%22middle%22%20font-family%3D%22Fantasy%22%20font-size%3D%2214%22%20id%3D%22questionMark%22%20y%3D%22181.249569%22%20x%3D%22155.549819%22%20stroke-width%3D%220%22%20stroke%3D%22%23666666%22%20fill%3D%22%23000000%22%3E%3F%3C/text%3E%0A%20%3C/g%3E%0A%3C/svg%3E" alt="Image preview" />
<input type="file" id="file1" style="display:none">
<button id="btn">選擇圖片</button>
<span id="msgName"></span>
<script>
btn.onclick = function(){
    file1.click();
}
file1.onchange = function(){
    var file = file1.files[0];
    //如果一個文件被選中
    if(file){
        //一張圖片被選中
        if (/image/.test(file.type)){
            var reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = function(){
                uploadPreview.src = reader.result;
                msgName.innerHTML = file.name;
            }
        //其他格式文件被選中
        } else {
            alert("You must select a valid image file!");
        }                
    }    
}
</script>

使用Blob也能顯示縮略圖

<input id="file1" type="file" accept="image/gif,image/jpeg,image/jpg,image/png,image/x-icon"  style="display:none">
<button id="btn">選擇圖片</button>
<div id="fileList"></div>
<script>
btn.onclick = function(){file1.click();}
//保存圖片的名稱
var dataArr = [];
file1.onchange = function(){
    var file = file1.files[0];
    //如果一個文件被選中
    if(file){
        var name = file.name;
        var id = name.split('.').join('_');
        //檢測圖片是否已經(jīng)被存儲過
        if(dataArr.indexOf(id) > -1){
            //將保存過的圖片轉(zhuǎn)移到最下方
            fileList.appendChild(document.getElementById(id));
        }else{
            if(/image/.test(file.type)){
                dataArr.push(id);
                var img = document.createElement('img');
                img.onload = function(){
                    URL.revokeObjectURL(img.src);
                }
                img.src= URL.createObjectURL(file);
                img.height = 60;
                var oDiv = document.createElement('div');
                oDiv.id = id;
                var oSpan = document.createElement('span');
                oSpan.innerHTML = name + ":" + file.size + " bytes";
                oDiv.appendChild(img);
                oDiv.appendChild(oSpan);
                fileList.appendChild(oDiv);                
            }
        }
    }    
}
</script>
讀取文件內(nèi)容
<input id="file1" type="file"  style="display:none">
<button id="btn">選擇文件</button>
<div id="fileData" style="border:1px solid black;width:300px;overflow:auto"></div>
<script>
btn.onclick = function(){file1.click();}
file1.onchange = function(){
    var file = file1.files[0];
    //如果一個文件被選中
    if(file){
        var reader = new FileReader();
        reader.readAsText(file);
        reader.onload = function(){
            fileData.innerHTML = reader.result;
        }
    }         
}
</script>
文件進(jìn)度
<input id="file1" type="file"  style="display:none">
<button id="btn">選擇文件</button>
<div id="fileData"></div>
<script>
btn.onclick = function(){file1.click();}
file1.onchange = function(){
    var file = file1.files[0];
    //如果一個文件被選中
    if(file){
        var reader = new FileReader();
        reader.readAsText(file);
        reader.onprogress = function(e){
            e = e || event;
            fileData.innerHTML = '文件進(jìn)度為:' + e.loaded + '/' + e.total;
        }
    }         
}
</script>
文件上傳

方法一:使用表單提交實現(xiàn)文件上傳
文件上傳最基本的方法是使用HTML表單選擇本地文件進(jìn)行上傳锡足,在form表單中通過<input type="file">標(biāo)記選擇本地文件似将。并且,必須在<form>元素中將enctype設(shè)置為"multipart/form-data"簿训,將method設(shè)置為"post"罐氨。
另外臀规,需要在<form>表單中設(shè)置一個hidden類型的input框,其中name值為MAX_FILE_SIZE的隱藏值域栅隐,通過設(shè)置其value值限制上傳文件的大小

<form action="pp.php" method="post" enctype="multipart/form-data">
    <input type="hidden" name="MAX_FILE_SIZE" value="1000000">
    <input type="file" name="file1">
    <button>上傳文件</button>
</form>

方法二:使用FormData實現(xiàn)文件上傳
創(chuàng)建一個FormData()對象塔嬉,通過它調(diào)用append()方法并傳入相應(yīng)的File對象作為參數(shù)。然后约啊,再把FormData對象傳遞給XHR的send()方法邑遏。

<input type="file" name="file1" id="file1">
<div id="result"></div>
<script>
var oFile = document.getElementById('file1');
oFile.onchange = function(e){
    //創(chuàng)建xhr對象
    var xhr;
    if(window.XMLHttpRequest){
        xhr = new XMLHttpRequest();
    }else{
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    };
    var data = new FormData();
    data.append('file',oFile.files[0])
    //異步接受響應(yīng)
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            if(xhr.status == 200){
                //實際操作
                result.innerHTML = xhr.responseText;
            }
        }
    }
    //發(fā)送請求
    xhr.open('post','pp.php',true);
    xhr.send(data);
}
</script>

方法三:使用File API實現(xiàn)文件上傳

<input type="file" name="file1" id="file1">
<div id="result"></div>
<script>
var oFile = document.getElementById('file1');
oFile.onchange = function(e){
    //創(chuàng)建xhr對象
    var xhr;
    if(window.XMLHttpRequest){
        xhr = new XMLHttpRequest();
    }else{
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    };
    var data = oFile.files[0];
    //異步接受響應(yīng)
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            if(xhr.status == 200){
                //實際操作
                result.innerHTML = xhr.responseText;
            }
        }
    }
    //發(fā)送請求
    xhr.open('post','pp.php',true);
    xhr.setRequestHeader("content-type",data.type);
    xhr.send(data);
}
</script>
刪除文件

使用<input type="file>控件選擇文件后,如何刪除文件呢恰矩?一般地记盒,有兩種方法。一種是使用form表單的reset()方法外傅,重置表單纪吮;另一種是將<input type="file>控件的value值置空,但第二種方法IE10-瀏覽器不支持萎胰。

<form id="myForm">
  <input type="file" id="myFile">
</form>
<button id="btn1">刪除文件方法1</button>
<button id="btn2">刪除文件方法2</button>
<script>
var myFile = document.getElementById('myFile');
var myForm = document.getElementById('myForm');
btn1.onclick = function(){
  myFile.value = '';
}
btn2.onclick = function(){
  myForm.reset();
}
</script>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末碾盟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子技竟,更是在濱河造成了極大的恐慌冰肴,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件榔组,死亡現(xiàn)場離奇詭異熙尉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)搓扯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門检痰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锨推,你說我怎么就攤上這事铅歼。” “怎么了换可?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵椎椰,是天一觀的道長。 經(jīng)常有香客問我沾鳄,道長俭识,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任洞渔,我火速辦了婚禮套媚,結(jié)果婚禮上缚态,老公的妹妹穿的比我還像新娘。我一直安慰自己堤瘤,他們只是感情好玫芦,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著本辐,像睡著了一般桥帆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上慎皱,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天老虫,我揣著相機(jī)與錄音,去河邊找鬼茫多。 笑死祈匙,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的天揖。 我是一名探鬼主播夺欲,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼今膊!你這毒婦竟也來了些阅?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤斑唬,失蹤者是張志新(化名)和其女友劉穎市埋,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恕刘,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡缤谎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了雪营。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片弓千。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡衡便,死狀恐怖献起,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情镣陕,我是刑警寧澤谴餐,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站呆抑,受9級特大地震影響岂嗓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鹊碍,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一厌殉、第九天 我趴在偏房一處隱蔽的房頂上張望食绿。 院中可真熱鬧,春花似錦公罕、人聲如沸器紧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽铲汪。三九已至,卻和暖如春罐柳,著一層夾襖步出監(jiān)牢的瞬間掌腰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工张吉, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留齿梁,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓芦拿,卻偏偏與公主長得像士飒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蔗崎,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

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