WEB 項目大文件上傳下載解決方案

需求:項目要支持大文件上傳功能,經(jīng)過討論,初步將文件上傳大小控制在500M內(nèi),因此自己需要在項目中進(jìn)行文件上傳部分的調(diào)整和配置,自己將大小都以501M來進(jìn)行限制。


第一步:

前端修改

由于項目使用的是BJUI前端框架,并沒有使用框架本身的文件上傳控件,而使用的基于jQuery的Uploadify文件上傳組件,在項目使用的jslib項目中找到了BJUI框架集成jQuery Uploadify的部分,這部分代碼封裝在bjui-all.js文件中,

在bjui-all.js文件中的全局變量定義中有以下部分代碼,這就是定義的有關(guān)于上傳的Uploadify控件的重要變量:

//文件上傳對象

function?FileUploader(fileLoc, mgr)

{

?var?_this =?this;

?this.id = fileLoc.id;

?this.ui = { msg:?null, process:?null, percent:?null, btn: { del:?null, cancel:?null,post:null,stop:null?}, div:?null};

?this.isFolder =?false;?//不是文件夾

?this.app = mgr.app;

?this.Manager = mgr;?//上傳管理器指針

?this.event = mgr.event;

?this.Config = mgr.Config;

?this.fields = jQuery.extend({}, mgr.Config.Fields, fileLoc.fields);//每一個對象自帶一個fields幅本

?this.State =?this.Config.state.None;

?this.uid =?this.fields.uid;

?this.fileSvr = {

?pid:?""

?, id:?""

?, pidRoot:?""

?, f_fdTask:?false

?, f_fdChild:?false

?, uid: 0

?, nameLoc:?""

?, nameSvr:?""

?, pathLoc:?""

?, pathSvr:?""

?, pathRel:?""

?, md5:?""

?, lenLoc:?"0"

?, sizeLoc:?""

?, FilePos:?"0"

?, lenSvr:?"0"

?, perSvr:?"0%"

?, complete:?false

?, deleted:?false

?};//json obj,服務(wù)器文件信息

?this.fileSvr = jQuery.extend(this.fileSvr, fileLoc);


?//準(zhǔn)備

?this.Ready =?function?()

?{

?this.ui.msg.text("正在上傳隊列中等待...");

?this.State =?this.Config.state.Ready;

?this.ui.btn.post.click(function?() {

?_this.ui.btn.post.hide();

?_this.ui.btn.del.hide();

?_this.ui.btn.cancel.hide();

?_this.ui.btn.stop.show();

?if?(!_this.Manager.IsPostQueueFull()) {

?_this.post();

?}

?else?{

?_this.ui.msg.text("正在上傳隊列中等待...");

?_this.State = _this.Config.state.Ready;

?$.each(_this.ui.btn,?function?(i, n) { n.hide(); });

?_this.ui.btn.del.show();

?//添加到隊列

?_this.Manager.AppendQueue(_this.fileSvr.id);

????????}

?});

?this.ui.btn.stop.click(function?() {

?_this.stop();

?});

?this.ui.btn.del.click(function?() {

?_this.stop();

?_this.remove();

?});

?this.ui.btn.cancel.click(function?() {

?_this.stop();

?_this.remove();

?//_this.PostFirst();//

?});

?};


?this.svr_error =?function?()

?{

?alert("服務(wù)器返回信息為空,請檢查服務(wù)器配置");

?this.ui.msg.text("向服務(wù)器發(fā)送MD5信息錯誤");

?//this.ui.btn.cancel.text("續(xù)傳");

?this.ui.btn.stop.hide();

?this.ui.btn.cancel.show();

?};

?this.svr_error_same_name =?function?() {???????

?this.ui.msg.text("服務(wù)器存在同名文件");

?this.ui.btn.stop.hide();

?this.ui.btn.cancel.show();

?};

?this.svr_create =?function?(sv)

?{

?if?(sv.value ==?null)

?{

?this.Manager.RemoveQueuePost(this.fileSvr.id);

?this.svr_error();?return;

?}

?if?(!sv.ret) {

?this.Manager.RemoveQueuePost(this.fileSvr.id);

?this.svr_error_same_name();?return;

?}


?var?str = decodeURIComponent(sv.value);//

?this.fileSvr = JSON.parse(str);//

?//服務(wù)器已存在相同文件,且已上傳完成

?if?(this.fileSvr.complete)

?{

?this.post_complete_quick();

?}?//服務(wù)器文件沒有上傳完成

?else

?{

?this.ui.process.css("width",?this.fileSvr.perSvr);

?this.ui.percent.text(this.fileSvr.perSvr);

?this.post_file();

?}

?};

?this.svr_update =?function?() {

?if?(this.fileSvr.lenSvr == 0)?return;

?var?param = { uid:?this.fields["uid"], offset:?this.fileSvr.lenSvr, lenSvr:?this.fileSvr.lenSvr, perSvr:?this.fileSvr.perSvr, id:?this.id, time:?new?Date().getTime() };

?$.ajax({

?type:?"GET"

?, dataType:?'jsonp'

?, jsonp:?"callback"?//自定義的jsonp回調(diào)函數(shù)名稱,默認(rèn)為jQuery自動生成的隨機函數(shù)名

?, url:?this.Config["UrlProcess"]

?, data: param

?, success:?function?(msg) {}

?, error:?function?(req, txt, err) { alert("更新文件進(jìn)度錯誤!"?+ req.responseText); }

?, complete:?function?(req, sta) { req =?null; }

?});

?};

?this.svr_remove =?function?()

?{

?var?param = { uid:?this.fields["uid"], id:?this.fileSvr.id, time:?new?Date().getTime() };

?$.ajax({

?type:?"GET"

?, dataType:?'jsonp'

?, jsonp:?"callback"?//自定義的jsonp回調(diào)函數(shù)名稱,默認(rèn)為jQuery自動生成的隨機函數(shù)名

?, url:?this.Config["UrlDel"]

?, data: param

?, success:?function?(msg) { }

?, error:?function?(req, txt, err) { alert("刪除文件失??!"?+ req.responseText); }

?, complete:?function?(req, sta) { req =?null; }

?});

?};

?this.post_process =?function?(json)

?{

?this.fileSvr.lenSvr = json.lenSvr;//保存上傳進(jìn)度

?this.fileSvr.perSvr = json.percent;

?this.ui.percent.text("("+json.percent+")");

?this.ui.process.css("width", json.percent);

?var?str = json.lenPost +?" "?+ json.speed +?" "?+ json.time;

?this.ui.msg.text(str);

?};

?this.post_complete =?function?(json)

?{

?this.fileSvr.perSvr =?"100%";

?this.fileSvr.complete =?true;

?$.each(this.ui.btn,?function?(i, n)

?{

?n.hide();

?});

?this.ui.process.css("width",?"100%");

?this.ui.percent.text("(100%)");

?this.ui.msg.text("上傳完成");

?this.Manager.arrFilesComplete.push(this);

?this.State =?this.Config.state.Complete;

??????//從上傳列表中刪除

?this.Manager.RemoveQueuePost(this.fileSvr.id);

?//從未上傳列表中刪除

?this.Manager.RemoveQueueWait(this.fileSvr.id);


?var?param = { md5:?this.fileSvr.md5, uid:?this.uid, id:?this.fileSvr.id, time:?new?Date().getTime() };


?$.ajax({

?type:?"GET"

?, dataType:?'jsonp'

?, jsonp:?"callback"?//自定義的jsonp回調(diào)函數(shù)名稱,默認(rèn)為jQuery自動生成的隨機函數(shù)名

?, url: _this.Config["UrlComplete"]

?, data: param

?, success:?function?(msg)

?{

??_this.event.fileComplete(_this);//觸發(fā)事件

??_this.post_next();

?}

?, error:?function?(req, txt, err) { alert("文件-向服務(wù)器發(fā)送Complete信息錯誤!"?+ req.responseText); }

?, complete:?function?(req, sta) { req =?null; }

?});

?};

?this.post_complete_quick =?function?()

?{

???this.fileSvr.perSvr =?"100%";

?this.fileSvr.complete =?true;

?this.ui.btn.stop.hide();

?this.ui.process.css("width",?"100%");

?this.ui.percent.text("(100%)");

?this.ui.msg.text("服務(wù)器存在相同文件,快速上傳成功。");

?this.Manager.arrFilesComplete.push(this);

?this.State =?this.Config.state.Complete;

?//從上傳列表中刪除

?this.Manager.RemoveQueuePost(this.fileSvr.id);

?//從未上傳列表中刪除

?this.Manager.RemoveQueueWait(this.fileSvr.id);

?//添加到文件列表

?this.post_next();

?this.event.fileComplete(this);//觸發(fā)事件

?};

?this.post_stoped =?function?(json)

?{

?this.ui.btn.post.show();

?this.ui.btn.del.show();

?this.ui.btn.cancel.hide();

?this.ui.btn.stop.hide();

?this.ui.msg.text("傳輸已停止....");


?if?(this.Config.state.Ready ==?this.State)

?{

?this.Manager.RemoveQueue(this.fileSvr.id);

?this.post_next();

?return;

?}

?this.State =?this.Config.state.Stop;

?//從上傳列表中刪除

?this.Manager.RemoveQueuePost(this.fileSvr.id);

?this.Manager.AppendQueueWait(this.fileSvr.id);//添加到未上傳列表

?//傳輸下一個

?this.post_next();

?};

?this.post_error =?function?(json)

?{

?this.svr_update();

?this.ui.msg.text(this.Config.errCode[json.value]);

?this.ui.btn.stop.hide();

?this.ui.btn.post.show();

?this.ui.btn.del.show();


?this.State =?this.Config.state.Error;

?//從上傳列表中刪除

?this.Manager.RemoveQueuePost(this.fileSvr.id);

?//添加到未上傳列表

?this.Manager.AppendQueueWait(this.fileSvr.id);

?this.post_next();

?};

?this.md5_process =?function?(json)

?{

?var?msg =?"正在掃描本地文件,已完成:"?+ json.percent;

?this.ui.msg.text(msg);

?};

?this.md5_complete =?function?(json)

?{

?this.fileSvr.md5 = json.md5;

?this.ui.msg.text("MD5計算完畢,開始連接服務(wù)器...");

?this.event.md5Complete(this, json.md5);//biz event


?var?loc_path = encodeURIComponent(this.fileSvr.pathLoc);

?var?loc_len =?this.fileSvr.lenLoc;

?var?loc_size =?this.fileSvr.sizeLoc;

?var?param = jQuery.extend({},?this.fields,?this.Config.bizData, { md5: json.md5, id:?this.fileSvr.id, lenLoc: loc_len, sizeLoc: loc_size, pathLoc: loc_path, time:?new?Date().getTime() });


?$.ajax({

?type:?"GET"

?, dataType:?'jsonp'

?, jsonp:?"callback"?//自定義的jsonp回調(diào)函數(shù)名稱,默認(rèn)為jQuery自動生成的隨機函數(shù)名

?, url:?this.Config["UrlCreate"]

?, data: param

?, success:?function?(sv)

?{

?_this.svr_create(sv);

?}

?, error:?function?(req, txt, err)

?{

?_this.Manager.RemoveQueuePost(_this.fileSvr.id);

?alert("向服務(wù)器發(fā)送MD5信息錯誤!"?+ req.responseText);

?_this.ui.msg.text("向服務(wù)器發(fā)送MD5信息錯誤");

?_this.ui.btn.cancel.show();

?_this.ui.btn.stop.hide();

?}

?, complete:?function?(req, sta) { req =?null; }

?});

?};

?this.md5_error =?function?(json)

?{

?this.ui.msg.text(this.Config.errCode[json.value]);

?//文件大小超過限制,文件大小為0

?if?("4"?== json.value

?||?"5"?== json.value)

?{

?this.ui.btn.stop.hide();

?this.ui.btn.cancel.show();

?}

?else

?{???????????

?this.ui.btn.post.show();

?this.ui.btn.stop.hide();

?}

?this.State =?this.Config.state.Error;

?//從上傳列表中刪除

?this.Manager.RemoveQueuePost(this.fileSvr.id);

?//添加到未上傳列表

?this.Manager.AppendQueueWait(this.fileSvr.id);


?this.post_next();

?};

?this.post_next =?function?()

?{

?var?obj =?this;

?setTimeout(function?() { obj.Manager.PostNext(); }, 300);

?};

?this.post =?function?()

?{

?this.Manager.AppendQueuePost(this.fileSvr.id);

?this.Manager.RemoveQueueWait(this.fileSvr.id);

?if?(this.fileSvr.md5.length > 0 ||?this.fileSvr.lenSvr > 0)

?{

?this.post_file();

?}

?else

?{

?this.check_file();

?}

?};

?this.post_file =?function?()

?{

?$.each(this.ui.btn,?function?(i, n) { n.hide();});

?this.ui.btn.stop.show();

?this.State =?this.Config.state.Posting;//

?this.app.postFile({ id:?this.fileSvr.id, pathLoc:?this.fileSvr.pathLoc, pathSvr:this.fileSvr.pathSvr,lenSvr:?this.fileSvr.lenSvr, fields:?this.fields });

?};

?this.check_file =?function?()

?{

?//this.ui.btn.cancel.text("停止").show();

?this.ui.btn.stop.show();

?this.ui.btn.cancel.hide();

?this.State =?this.Config.state.MD5Working;

?this.app.checkFile({ id:?this.fileSvr.id, pathLoc:?this.fileSvr.pathLoc });

?};

?this.stop =?function?()

?{

?$.each(this.ui.btn,?function?(i, n) { n.hide();});

?this.svr_update();

?this.app.stopFile({ id:?this.fileSvr.id });???????

?};

?//手動停止,一般在StopAll中調(diào)用

?this.stop_manual =?function?()

?{

?if?(this.Config.state.Posting ==?this.State)

?{

?this.svr_update();

?this.ui.btn.post.show();

?this.ui.btn.stop.hide();

?this.ui.btn.cancel.hide();

?this.ui.msg.text("傳輸已停止....");

?this.app.stopFile({ id:?this.fileSvr.id ,tip:false});

?this.State =?this.Config.state.Stop;

?}

?};


?//刪除,一般在用戶點擊"刪除"按鈕時調(diào)用

?this.remove =?function?()

?{

?this.Manager.del_file(this.fileSvr.id);

?this.app.delFile(this.fileSvr);

?this.ui.div.remove();

?if?(this.State !=?this.Config.state.Complete)?this.svr_remove();

?};

}

upload:{uploadLimit:5,fileSizeLimit:31744,removeTimeout:0.8}

以上三個變量代表的含義是:

uploadLimit:表示上傳文件個數(shù)的限制,5表示文件上傳個數(shù)限制是5個

fileSizeLimit:表示上傳文件大小的限制,31744單位是KB,也就是表示31M

removeTimeout:表示移除文件的時間限制

繼續(xù)查找使用到這些變量的地方,看到了文件大小超出限制等

了解了BJUI前端框架對于上傳大文件的限制,可以這樣使用,增大文件上傳大小和數(shù)量,可以按照如下進(jìn)行修改,我們在bjui-all.js文件看到uploadLimit屬性和fileSizeLimit屬性的限制,我們在jsp文件中可以這樣進(jìn)行替換,這里使用的是覆蓋原則,重新定義uploadLimit屬性和fileSizeLimit屬性,覆蓋bjui-all.js文件的默認(rèn)值設(shè)置。


bjui-all.js文件的uploadLimit屬性和fileSizeLimit屬性對應(yīng)到j(luò)sp文件中的屬性就應(yīng)該這樣寫,data-upload-limit屬性和data-file-size-limit屬性,只需要在后面改寫為data-upload-limit=“800”和data-file-size-limit=“5131264”即可,一定要注意這里的單位是KB,以上數(shù)字表示501M。


關(guān)于Uploadify控件屬性可以參考這篇文章也可以直接看官網(wǎng)文檔:

http://blog.ncmem.com/wordpress/2019/08/07/java超大文件上傳與下載/

屬性名稱默認(rèn)值說明

autotrue設(shè)置為true當(dāng)選擇文件后就直接上傳了,為false需要點擊上傳按鈕才上傳 。

buttonClass”按鈕樣式

buttonCursor‘hand’鼠標(biāo)指針懸停在按鈕上的樣子

buttonImagenull瀏覽按鈕的圖片的路徑 。

buttonText‘SELECT FILES’瀏覽按鈕的文本。

checkExistingfalse文件上傳重復(fù)性檢查程序,檢查即將上傳的文件在服務(wù)器端是否已存在,存在返回1,不存在返回0

debugfalse如果設(shè)置為true則表示啟用SWFUpload的調(diào)試模式

fileObjName‘Filedata’文件上傳對象的名稱,如果命名為’the_files’,PHP程序可以用$_FILES['the_files']來處理上傳的文件對象。

fileSizeLimit0上傳文件的大小限制 ,如果為整數(shù)型則表示以KB為單位的大小,如果是字符串,則可以使用(B, KB, MB, or GB)為單位,比如’2MB’;

如果設(shè)置為0則表示無限制

fileTypeDesc‘All Files’這個屬性值必須設(shè)置fileTypeExts屬性后才有效,用來設(shè)置選擇文件對話框中的提示文本,如設(shè)置fileTypeDesc為“請選擇rar doc pdf文件”

fileTypeExts‘*.*’設(shè)置可以選擇的文件的類型,格式如:’*.doc;*.pdf;*.rar’?。

formData?JSON格式上傳每個文件的同時提交到服務(wù)器的額外數(shù)據(jù),可在’onUploadStart’事件中使用’settings’方法動態(tài)設(shè)置。

height30設(shè)置瀏覽按鈕的高度 ,默認(rèn)值

itemTemplatefalse用于設(shè)置上傳隊列的HTML模版,可以使用以下標(biāo)簽:

??instanceID – ? Uploadify實例的ID

??fileID – 列隊中此文件的ID,或者理解為此任務(wù)的ID

??fileName – 文件的名稱

??fileSize – 當(dāng)前上傳文件的大小

??插入模版標(biāo)簽時使用格式如:${fileName}

methodPost提交方式Post或Get

multitrue設(shè)置為true時可以上傳多個文件。

overrideEvents?設(shè)置哪些事件可以被重寫,JSON格式,如:’overrideEvents’ : ['onUploadProgress']

preventCachingtrue如果為true,則每次上傳文件時自動加上一串隨機字符串參數(shù),防止URL緩存影響上傳結(jié)果

progressData‘percentage’設(shè)置上傳進(jìn)度顯示方式,percentage顯示上傳百分比,speed顯示上傳速度

queueIDfalse設(shè)置上傳隊列容器DOM元素的ID,如果為false則自動生成一個隊列容器。

queueSizeLimit999隊列最多顯示的任務(wù)數(shù)量,如果選擇的文件數(shù)量超出此限制,將會出發(fā)onSelectError事件。

??注意此項并非最大文件上傳數(shù)量,如果要限制最大上傳文件數(shù)量,應(yīng)設(shè)置uploadLimit。

removeCompletedtrue是否自動將已完成任務(wù)從隊列中刪除,如果設(shè)置為false則會一直保留此任務(wù)顯示。

removeTimeout3如果設(shè)置了任務(wù)完成后自動從隊列中移除,則可以規(guī)定從完成到被移除的時間間隔。

requeueErrorsfalse如果設(shè)置為true,則單個任務(wù)上傳失敗后將返回錯誤,并重新加入任務(wù)隊列上傳。

successTimeout30文件上傳成功后服務(wù)端應(yīng)返回成功標(biāo)志,此項設(shè)置返回結(jié)果的超時時間

swf‘uploadify.swf’uploadify.swf?文件的相對路徑。

uploaderuploadify.php后臺處理程序的相對路徑。

uploadLimit999最大上傳文件數(shù)量,如果達(dá)到或超出此限制將會觸發(fā)onUploadError事件。

width120設(shè)置文件瀏覽按鈕的寬度。

第二步:

后端修改

由于項目后端使用的Spring Boot,本身也就是使用的Spring MVC文件上傳部分,Spring MVC使用的是已經(jīng)對Servlet文件上傳封裝了的MultipartResolver接口及其相關(guān)實現(xiàn)類和一些相關(guān)的類,具體的可以看Spring MVC文件上傳源碼部分,認(rèn)為Spring源碼還是需要讀的,我們只要在Spring Boot啟動類中注入這個Bean,或者自行寫一個WebConfig配置類,注入一些Web相關(guān)的Bean即可,這樣Spring Boot啟動就會加載配置類,也需要自己寫攔截器和全局AOP切面,去捕捉文件上傳大小超過限制的異常處理等


基于Spring MVC文件上傳組件MultipartResolver接口(核心),使用其中的CommonsMultipartResolver(實現(xiàn)了MultipartResolver接口)這個實現(xiàn)類,CommonsMultipartResolver中的maxUploadSize屬性是它繼承的抽象父類CommonsFileUploadSupport,這個抽象類其中的一個屬性是FileUpload類,而這個類又繼承自FileUploadBase這個抽象類,其中它的private long sizeMax = -1;就是maxUploadSize屬性的最終設(shè)置地方。-1表示文件上傳大小沒有限制,但是我們一般都會設(shè)置一個限制值,這里設(shè)置的是210763776,這個值的單位是字節(jié),我們將它設(shè)置為525336576字節(jié),也就是501M的大小限制。


修改完以上前端和后端,提交修改的代碼到git上即可。


第三步:

Nginx配置

進(jìn)入到項目部署發(fā)布所在的Linux下,進(jìn)入nginx服務(wù)器所安裝的目錄,

進(jìn)入到nginx服務(wù)器所安裝的目錄

進(jìn)入到nginx服務(wù)器目錄下的conf目錄

查看nginx.conf配置文件內(nèi)容中的client_max_body_size配置的大小,這里設(shè)置的是300M。

使用vi或者vim打開nginx.conf配置文件,修改client_max_body_size的大小為501M,保存即可

進(jìn)入到nginx服務(wù)器下的sbin目錄下,我們使用./nginx -t查看配置文件是否成功使用,然后使用./nginx -s reload重啟Nginx服務(wù)器即可。


第四步:

Tomcat配置

由于項目使用的是Spring Cloud,自然使用Spring Boot,我們這個項目還是使用外置的Tomcat作為他的服務(wù)器,便于我們對Tomcat服務(wù)器進(jìn)行優(yōu)化和設(shè)置。

進(jìn)入到項目使用的Tomcat服務(wù)器的目錄

進(jìn)入到指定項目使用的Tomcat服務(wù)器的目錄

進(jìn)入到Tomcat服務(wù)器下的conf配置目錄中

看到server.xml配置文件后

先行查看Tomcat服務(wù)器的配置,其中兩個屬性對于這次是比較重要的一個是connectionTimeout這個連接超時時間設(shè)置以及默認(rèn)的maxPostSize屬性的設(shè)置

使用vi或者vim打開server.xml配置文件,修改connectionTimeout的大小為2000000,這個屬性的單位是毫秒,換算之后大概是半個小時,我們配置缺省的maxPostSize屬性的值,默認(rèn)情況下它的值是2097152,它的單位是字節(jié),也就是2M的大小,修改完保存即可

修改完服務(wù)器之后,使用發(fā)布工具重新從git上拉取最新的代碼和部署發(fā)布,重新啟動腳本即可完成修改,再次嘗試大文件上傳,功能基本實現(xiàn)。


以上需要注意的是maxPostSize屬性在各個Tomcat版本中的不同,詳細(xì)源碼可以網(wǎng)上搜索“up6文件上傳”

討論群:374992201

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

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