nuxt.js實(shí)現(xiàn)服務(wù)端渲染ssr(環(huán)境配置纲熏、 多環(huán)境開(kāi)發(fā)、進(jìn)程守護(hù)锄俄、服務(wù)端鏡像)

nuxt.js是一個(gè)基于 Vue.js 的輕量級(jí)應(yīng)用框架,可用來(lái)創(chuàng)建服務(wù)端渲染 (SSR) 應(yīng)用,也可充當(dāng)靜態(tài)站點(diǎn)引擎生成靜態(tài)站點(diǎn)應(yīng)用——nuxt官網(wǎng)

images.png

根據(jù)自己在這上方面一條路走到黑局劲,摸滾帶爬的踩坑經(jīng)驗(yàn),接下來(lái)我將從以下幾個(gè)方面給各位接觸到或者未來(lái)接觸到這方面知識(shí)的碼友進(jìn)行全方位的講解和剖析奶赠。

  1. 背景
  2. nuxt框架的概述
  3. 百度蜘蛛爬蟲(chóng)的機(jī)制
  4. nuxt初探(開(kāi)發(fā)環(huán)境搭建)
  5. 深入nuxt ssr(服務(wù)端渲染)
  6. 多環(huán)境配置 (開(kāi)發(fā)鱼填、測(cè)試、生產(chǎn))
  7. Nginx反向代理
  8. pm2守護(hù)node進(jìn)程配置
  9. 服務(wù)端docker容器部署前端工程
  10. 總結(jié)
背景

最近因公司業(yè)務(wù)需求毅戈,需要對(duì)商城官網(wǎng)做seo優(yōu)化苹丸。因?yàn)榈谝话媲岸擞玫氖羌僾ue寫(xiě)的,經(jīng)Vue-cli集成的webpack打包還有代碼壓縮處理后生成一串js的靜態(tài)文件苇经。因百度蜘蛛無(wú)法對(duì)純js的網(wǎng)頁(yè)進(jìn)行爬取收錄赘理。所以不利于網(wǎng)站的排名。緊接我們和領(lǐng)導(dǎo)開(kāi)會(huì)拍板使用服務(wù)端渲染(以下用ssr指代)扇单,nuxt剛好是vue團(tuán)隊(duì)打造的基于vue的ssr的框架商模,簡(jiǎn)單易于上手,避免了前端攻城獅們自己用node.js搭建服務(wù)蜘澜。但初始我們采用的是nuxt的靜態(tài)化部署施流,nuxt generate ,這樣可以解決一部分需求鄙信,但每次更新內(nèi)容后都要前端手動(dòng)執(zhí)行命令打包瞪醋。而且通過(guò)百度蜘蛛爬取趨勢(shì)圖顯示這種方式并不理想。最后扮碧,我們還是在原來(lái)的基礎(chǔ)上采用nuxt的第二種方式前端做ssr處理趟章,上線(xiàn)后經(jīng)百度蜘蛛爬取趨勢(shì)圖顯示有很大程度的提高杏糙,利于seo,且官網(wǎng)被百度收錄的頁(yè)面也逐漸增加蚓土。由此告一段落宏侍。

nuxt框架的概述

nuxt作為一個(gè)框架,則集成了vue2蜀漆、vue-route谅河、vuex、vue ssr确丢、vue-meta等組件/框架绷耍,其是用webpack、和vue-loader鲜侥、babel-loader來(lái)處理代碼的自動(dòng)化構(gòu)建工作(打包褂始、代碼分層、壓縮等)
nuxt框架提供了兩種部署方式:
1. 靜態(tài)化部署(預(yù)渲染)-- 通過(guò) nuxt generate 命令實(shí)現(xiàn)描函。該命令依據(jù)應(yīng)用的路由配置將每一個(gè)路由靜態(tài)化成為對(duì)應(yīng)的 HTML 文件
2. ssr部署 -- 先通過(guò)nuxt build編譯構(gòu)建再通過(guò)nuxt start開(kāi)啟一個(gè)web服務(wù)
在服務(wù)端調(diào)取接口時(shí)崎苗,主要是用到了asyncData/fetch方法。使得我們可以在設(shè)置組件的數(shù)據(jù)之前能異步獲取或處理數(shù)據(jù)舀寓。

asyncData方法會(huì)在組件(限于頁(yè)面組件)每次加載之前被調(diào)用胆数。它可以在服務(wù)端或路由更新之前被調(diào)用。 在這個(gè)方法被調(diào)用的時(shí)候互墓,第一個(gè)參數(shù)被設(shè)定為當(dāng)前頁(yè)面的上下文對(duì)象必尼,你可以利用 asyncData方法來(lái)獲取數(shù)據(jù),Nuxt.js 會(huì)將 asyncData 返回的數(shù)據(jù)融合組件 data 方法返回的數(shù)據(jù)一并返回給當(dāng)前組件篡撵。

注意:由于asyncData方法是在組件 初始化 前被調(diào)用的判莉,所以在方法內(nèi)是沒(méi)有辦法通過(guò) this 來(lái)引用組件的實(shí)例對(duì)象。

fetch 方法用于在渲染頁(yè)面前填充應(yīng)用的狀態(tài)樹(shù)(store)數(shù)據(jù)酸休, 與 asyncData 方法類(lèi)似骂租,不同的是它不會(huì)設(shè)置組件的數(shù)據(jù)。
類(lèi)型: Function
如果頁(yè)面組件設(shè)置了 fetch 方法斑司,它會(huì)在組件每次加載前被調(diào)用(在服務(wù)端或切換至目標(biāo)路由之前)。fetch 方法的第一個(gè)參數(shù)是頁(yè)面組件的上下文對(duì)象 context但汞,我們可以用 fetch 方法來(lái)獲取數(shù)據(jù)填充應(yīng)用的狀態(tài)樹(shù)宿刮。為了讓獲取過(guò)程可以異步,你需要返回一個(gè) Promise私蕾,Nuxt.js 會(huì)等這個(gè) promise 完成后再渲染組件僵缺。

警告: 您無(wú)法在內(nèi)部使用this獲取組件實(shí)例,fetch是在組件初始化之前被調(diào)用

大概了解了這些知識(shí)就可以做ssr工作了踩叭,路由 環(huán)境配置等可到中文官網(wǎng)https://zh.nuxtjs.org 查閱

百度蜘蛛爬蟲(chóng)的機(jī)制

百度蜘蛛是百度搜索引擎的一個(gè)自動(dòng)化程序磕潮,它會(huì)不斷的訪(fǎng)問(wèn)收集互聯(lián)網(wǎng)上的網(wǎng)頁(yè)翠胰、文章、視頻等自脯,通過(guò)抓取鏈接來(lái)收錄網(wǎng)站之景,計(jì)算網(wǎng)站的權(quán)重和排名。純html等靜態(tài)化網(wǎng)站對(duì)百度蜘蛛比較友好膏潮,且百度蜘蛛幾乎不會(huì)爬取js動(dòng)態(tài)的網(wǎng)站锻狗,如vue/react構(gòu)建的且經(jīng)webpack/gulp等構(gòu)建工具壓縮處理過(guò)的網(wǎng)站。百度蜘蛛爬取網(wǎng)站是從主站開(kāi)始爬焕参,一次根據(jù)網(wǎng)站暴露的內(nèi)鏈依次往深層次爬取轻纪。meta的設(shè)置,以及網(wǎng)站TDK的優(yōu)化叠纷,網(wǎng)站結(jié)構(gòu)優(yōu)化刻帚,外鏈,文章原創(chuàng)等同樣對(duì)SEO有很大作用涩嚣,但本文主要是從技術(shù)層面入手我擂,則主要是針對(duì)網(wǎng)站內(nèi)鏈的處理以及基于vue等現(xiàn)在技術(shù)流做ssr處理。

nuxt初探(開(kāi)發(fā)環(huán)境搭建)
安裝

我這里采用nuxt.js團(tuán)隊(duì)創(chuàng)建的腳手架creat-nuxt-app搭建缓艳。
注: 開(kāi)發(fā)必備環(huán)境 npx (npm v5.2.0+) node (v4.0+)
我的開(kāi)發(fā)環(huán)境npm v5.5.1 node v8.9.1 win10
在終端輸入以下命令

npx create-nuxt-app nuxt-demo

然后你會(huì)看到

nuxt-1.png

nuxt-2.png

當(dāng)執(zhí)行命令

npm run dev

當(dāng)你看到如下圖恭喜你成功搭建起項(xiàng)目


nuxt-3.png

當(dāng)你和后端交互時(shí)校摩,為了解決跨域問(wèn)題這邊需要通過(guò)proxy利用本地node服務(wù)器做個(gè)反向代理
在nuxt.config.js中配置

module.exports= {
    modules: [
        '@nuxtjs/axios'
    ],
    axios: {
        proxy: true, //開(kāi)啟代理
        credentials: true, //跨域請(qǐng)求需使用憑證
    },
    proxy: [
        ['/api',{ 
            target: 'http://example.com/api', // (后端請(qǐng)求地址)
            changeOrigin: true,
            pathRewrite: {'^/api': ''}
        }]
    ]
}

附上剛搭建完的nuxt.config.js和package.json

// nuxt.config.js

module.exports = {
  mode: 'universal',
  /*
  ** Headers of the page
  */
  head: {
    title: process.env.npm_package_name || '',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  /*
  ** Customize the progress-bar color
  */
  loading: { color: '#fff' },
  /*
  ** Global CSS
  */
  css: [
    'element-ui/lib/theme-chalk/index.css'
  ],
  /*
  ** Plugins to load before mounting the App
  */
  plugins: [
    '@/plugins/element-ui'
  ],
  /*
  ** Nuxt.js dev-modules
  */
  buildModules: [
    // Doc: https://github.com/nuxt-community/eslint-module
    '@nuxtjs/eslint-module',
  ],
  /*
  ** Nuxt.js modules
  */
  modules: [
    // Doc: https://axios.nuxtjs.org/usage
    '@nuxtjs/axios',
    '@nuxtjs/pwa',
    // Doc: https://github.com/nuxt-community/dotenv-module
    '@nuxtjs/dotenv',
  ],
  /*
  ** Axios module configuration
  ** See https://axios.nuxtjs.org/options
  */
  axios: {
  },
  /*
  ** Build configuration
  */
  build: {
    transpile: [/^element-ui/],
    /*
    ** You can extend webpack config here
    */
    extend (config, ctx) {
    }
  }
}

//package.json
{
  "name": "nuxt-demo",
  "version": "1.0.0",
  "description": "for a nuxt demo about ssr",
  "author": "kevin xie",
  "private": true,
  "scripts": {
    "dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
    "build": "nuxt build",
    "start": "cross-env NODE_ENV=production node server/index.js",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
    "test": "jest"
  },
  "dependencies": {
    "nuxt": "^2.0.0",
    "cross-env": "^5.2.0",
    "express": "^4.16.4",
    "element-ui": "^2.4.11",
    "@nuxtjs/axios": "^5.3.6",
    "@nuxtjs/pwa": "^3.0.0-0",
    "@nuxtjs/dotenv": "^1.4.0"
  },
  "devDependencies": {
    "nodemon": "^1.18.9",
    "@nuxtjs/eslint-config": "^2.0.0",
    "@nuxtjs/eslint-module": "^1.0.0",
    "babel-eslint": "^10.0.1",
    "eslint": "^6.1.0",
    "eslint-plugin-nuxt": ">=0.4.2",
    "@vue/test-utils": "^1.0.0-beta.27",
    "babel-jest": "^24.1.0",
    "jest": "^24.1.0",
    "vue-jest": "^4.0.0-0"
  }
}

深入nuxt ssr(服務(wù)端渲染)

如果你不需要做ssr處理的話(huà)直接執(zhí)行nuxt generate則nuxt會(huì)為你生成靜態(tài)化頁(yè)面 ,然后再執(zhí)行nuxt build 打包后將dist文件夾推上服務(wù)器就可以上線(xiàn)了阶淘,但這種seo不太友好但比之前vue構(gòu)建好一點(diǎn)衙吩。
但要做ssr處理的話(huà)就需換種方式處理也就是nuxt提供的第二種方式,在服務(wù)器搭個(gè)node服務(wù)器然后直接在上面跑溪窒。這樣的話(huà)坤塞,配置需要改,且與后臺(tái)的請(qǐng)求也需要改澈蚌,改為nuxt給我們提供asyncData/fetch摹芙。因?yàn)閚uxt也是基于vue開(kāi)發(fā)的,所以生命周期也一樣宛瞄,但nuxt在服務(wù)端中會(huì)觸發(fā)beforeCreate 浮禾、created兩個(gè)生命周期。其次份汗,nuxt有自己一套服務(wù)器渲染流程盈电。


nuxt-4.PNG

Nuxt.js 提供了幾種不同的方法來(lái)使用 asyncData 方法,你可以選擇自己熟悉的一種來(lái)用:

  1. 返回一個(gè) Promise, nuxt.js會(huì)等待該P(yáng)romise被解析之后才會(huì)設(shè)置組件的數(shù)據(jù)杯活,從而渲染組件.
  2. 使用 async 或 await
  3. 使用回調(diào)函數(shù)
返回Promise
export default {
  asyncData ({ params }) {
    return axios.get(`https://my-api/posts/${params.id}`)
      .then((res) => {
        return { title: res.data.title }
      })
  }
}
使用async或await
export default {
  async asyncData ({ params }) {
    const { data } = await axios.get(`https://my-api/posts/${params.id}`)
    return { title: data.title }
  }
}
使用回調(diào)函數(shù)
export default {
  asyncData ({ params }, callback) {
    axios.get(`https://my-api/posts/${params.id}`)
      .then((res) => {
        callback(null, { title: res.data.title })
      })
  }
}

另外匆帚,還要注意一下在做登錄處理等需要獲取cookie或者服務(wù)端存儲(chǔ)的session時(shí),需要使用到vuex狀態(tài)樹(shù)旁钧,在狀態(tài)樹(shù)中有個(gè)方法非常有用 nuxtServerInit

actions: {
  nuxtServerInit ({ commit }, { req }) {
    if (req.session.user) {
      commit('user', req.session.user)
    }
  }
}
多環(huán)境配置 (開(kāi)發(fā)吸重、測(cè)試互拾、生產(chǎn))

因?yàn)樵谝粋€(gè)工程項(xiàng)目中我們都是有開(kāi)發(fā)、測(cè)試嚎幸、生產(chǎn)這樣的驗(yàn)收流程的颜矿。而往往我們測(cè)試和生產(chǎn)所連接的數(shù)據(jù)庫(kù)都是不同的,且請(qǐng)求域也不一樣鞭铆。因此為了開(kāi)發(fā)方便我們就很需要多環(huán)境的配置或衡。在spa中我們可以在package.json中通過(guò)cross-env這個(gè)node環(huán)境變量設(shè)置,但在ssr中這個(gè)在服務(wù)端請(qǐng)求時(shí)不生效车遂,這里我當(dāng)時(shí)找了很久google之類(lèi)最后還是通過(guò)@nuxtjs/dotenv解決了封断。還有特別注意到@nuxtjs/axios中有提供環(huán)境變量API_URL來(lái)復(fù)寫(xiě)baseURL和API_URL_BROWSER來(lái)復(fù)寫(xiě)browserBaseURL,這在多環(huán)境配置中很有用。
你可以在nuxt.config.js中引入并且在module中使用舶担。

require('dotenv').config({path: '.env'})
module.exports={
    modules: [
        '@nuxtjs/axios',
        '@nuxtjs/dotenv'
    ]
}

同時(shí)你可以在根目錄下配置相關(guān)環(huán)境配置文件坡疼。

.env.dev

NODE_ENV=development
API_URL_BROWSER=http://localhost:3000
API_URL=http://localhost:3000/api

.env.test

NODE_ENV=test
API_URL_BROWSER=http://test.example.com
API_URL=http://test.example.com/api

.env.prod

NODE_ENV=production
API_URL_BROWSER=https://www.example.com
API_URL=https://www.example.com/api

當(dāng)你用axios做跨域請(qǐng)求時(shí),你就可以自動(dòng)根據(jù)環(huán)境給axios配置baseURL衣陶。

import axios from 'axios';
const axiosInstance = axios.create({
    timeout: 10000,
    baseURL: process.env.API_URL
})

在某些需要跳轉(zhuǎn)的鏈接nuxt-link或a鏈接中你可以聲明一個(gè)變量對(duì)域名做統(tǒng)一處理柄瑰。

export default {
    data () {
        return {
            BASE_PATH: process.env.API_URL_BROWSER
        }
    }
}
Nginx反向代理

在生成環(huán)境中,我需要使用到nginx做代理服務(wù)器剪况,解決跨域教沾。因?yàn)槲覀兊捻?xiàng)目的前后端可能部署在不同的服務(wù)上。

upstream nodenuxt {
    server 127.0.0.1:3000; #nuxt項(xiàng)目 監(jiān)聽(tīng)端口
    keepalive 64;
}
server {
    listen 80;
    server_name https://www.example.com; #訪(fǎng)問(wèn)域名  
    location / {
        proxy_http_version 1.1;        
        proxy_set_header Upgrade $http_upgrade;  
        proxy_set_header Connection "upgrade";        
        proxy_set_header Host $host;        
        proxy_set_header X-Nginx-Proxy true;        
        proxy_cache_bypass $http_upgrade;        
        proxy_pass http://nodenuxt; #反向代理
    }
}
pm2守護(hù)node進(jìn)程配置

當(dāng)我們配置以上內(nèi)容后在服務(wù)端執(zhí)行npm start項(xiàng)目可以跑起來(lái)译断,但我們的項(xiàng)目總會(huì)掛掉的授翻,為了使我們服務(wù)進(jìn)程常駐,我們要用到pm2來(lái)守護(hù)node進(jìn)程孙咪。并且可以用它來(lái)做自動(dòng)重啟堪唐、性能監(jiān)控以及負(fù)載均衡。
你可以全局安裝npm install pm2 -g
其他麻油說(shuō) 執(zhí)行命令可以成功翎蹈,但我這邊還是沒(méi)成功pm2 start npm --name "nuxt-demo" -- run start //(nuxt-demo為你的package.json中的項(xiàng)目名)
我們知道package.json這個(gè)文件淮菠,當(dāng)我們執(zhí)行npm run dev的時(shí)候,其實(shí)使用npm去啟動(dòng)了./node_modules/nuxt/bin/nuxt這個(gè)文件荤堪。當(dāng)我們cd到我們的項(xiàng)目目錄之后合陵,我們最終可以執(zhí)行如下命令來(lái)啟動(dòng):

pm2 start ./node_modules/nuxt/bin/nuxt.js -- start

這樣可以將項(xiàng)目跑起來(lái),但當(dāng)項(xiàng)目報(bào)錯(cuò)時(shí)我們無(wú)法看到日志逞力,因此我這里在根目錄通過(guò)配置pm2.config.js曙寡。

module.exports = {
    apps: [
        {
            name: 'nuxt-demo',//項(xiàng)目名稱(chēng)
            cwd: './',//當(dāng)前工作路徑
            #script: 'npm',//實(shí)際啟動(dòng)腳本
                          script: './node_modules/nuxt/bin/nuxt.js ',//或者直接執(zhí)行這個(gè)腳本
            args: 'run start',//參數(shù)
            autorestart: true, //自動(dòng)重啟
            error_file: 'logs/nuxt-demo-err.log',//錯(cuò)誤日志
            out_file: 'logs/nuxt-demo-out.log', //正常運(yùn)行日志
            exec_mode: 'cluster',// 應(yīng)用啟動(dòng)模式,支持fork和cluster模式
            min_uptime: '60s', //應(yīng)用運(yùn)行少于時(shí)間被認(rèn)為是異常啟動(dòng)
            restart_delay: '60s',//重啟時(shí)延
            instances: 4,//開(kāi)啟4個(gè)實(shí)例寇荧,僅在cluster模式有效,用于負(fù)載均衡
            watch: true,//監(jiān)控變化的目錄执隧,一旦變化揩抡,自動(dòng)重啟
            watch: ['.nuxt', 'nuxt.config.js'],//監(jiān)控變化的目錄
            watch_delay: 1000,//監(jiān)控時(shí)延
            ignore_watch: ['node_modules'],//從監(jiān)控目錄中排除
            watch_options: { // 監(jiān)聽(tīng)配置
                'followSymlinks': false,
                'usePolling': true
            }
        }
    ]
}

這里我是在package.json中引用這個(gè)配置文件的户侥。在服務(wù)器中執(zhí)行命令就行。(若有報(bào)錯(cuò)可能需要安裝babel轉(zhuǎn)譯 ```npm install babel-cli babel-core babel-preset-es2015 --save-dev)

{
    "scripts": {
        "dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server --exec babel-node",
        "build": "nuxt build",
        "start:test": "cross-env NODE_ENV=test node server/index.js pm2 start pm2.config.js --exec babel-node",
        "start:prod": "cross-env NODE_ENV=production node server/index.js pm2 start pm2.config.js --exec babel-node",
    }
}
服務(wù)端docker容器部署前端工程

建立Dockerfile 參考這篇文章

FROM node:alpine

RUN mkdir -p /app/src
COPY ./src /app/src
WORKDIR /app/src

ENV HOST "0.0.0.0"

RUN sed -i "s/dl-cdn.alpinelinux.org/${ALPINE_REPOSITORIES}/g" /etc/apk/repositories

RUN apk add --no-cache make gcc g++ python

RUN npm config set registry https://registry.npm.taobao.org
RUN npm install -g pm2
RUN npm install
RUN npm run build
RUN npm cache clean --force

RUN apk del make gcc g++ python

EXPOSE 3000
CMD ["npm", "run", "start:test"]
#CMD ["npm", "run", "start:prod"]

然后構(gòu)建鏡像

docker build -t nuxt-demo

啟動(dòng)容器

docker run -dt -p 3000:3000 nuxt-demo

注意:這里服務(wù)端部署后需要0.0.0.0:3000訪(fǎng)問(wèn)峦嗤,則我們前端還需配置主機(jī)號(hào)和端口蕊唐,我這邊在package.json中沒(méi)成功,在nuxt.config.js中配置成功了烁设。

module.exports = {
    server: {
        host: '0.0.0.0',
        port: 3000
    }
}
總結(jié)

總得來(lái)說(shuō)替梨,在coding world中要不斷的學(xué)習(xí),沒(méi)什么問(wèn)題解決不了装黑,堅(jiān)持就對(duì)了副瀑。若有小伙伴對(duì)以上內(nèi)容有不解歡迎評(píng)論,我會(huì)盡力為你答疑解惑的恋谭。最后喜歡這篇文章的小伙伴關(guān)注一下小生并點(diǎn)個(gè)贊糠睡。
附:

史記·大疫

己亥末,庚子春疚颊,荊楚大疫狈孔,染者數(shù)萬(wàn),眾惶恐材义,舉國(guó)防均抽,皆閉戶(hù),道無(wú)車(chē)舟其掂,萬(wàn)巷空寂油挥。然外狼亦動(dòng),垂涎而候清寇,華夏腹背芒刺喘漏。幸龍魂不死,風(fēng)雨而立华烟。醫(yī)無(wú)私翩迈,警無(wú)畏,民齊心盔夜!政者负饲,醫(yī)者,兵者喂链,扛鼎逆行勇戰(zhàn)矣返十!商客,名家椭微,百姓洞坑,仁義者,鄰邦獻(xiàn)物捐資蝇率,嘆山川異域迟杂,風(fēng)月同天刽沾,豈曰無(wú)衣,與子同裳排拷!能者竭力侧漓,萬(wàn)民同心。月余监氢,疫除布蔗,終勝。此后百年浪腐,風(fēng)調(diào)雨順纵揍,國(guó)泰民安!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末牛欢,一起剝皮案震驚了整個(gè)濱河市骡男,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌傍睹,老刑警劉巖隔盛,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異拾稳,居然都是意外死亡吮炕,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)访得,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)龙亲,“玉大人,你說(shuō)我怎么就攤上這事悍抑■” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵搜骡,是天一觀(guān)的道長(zhǎng)拂盯。 經(jīng)常有香客問(wèn)我,道長(zhǎng)记靡,這世上最難降的妖魔是什么谈竿? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮摸吠,結(jié)果婚禮上空凸,老公的妹妹穿的比我還像新娘。我一直安慰自己寸痢,他們只是感情好呀洲,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般两嘴。 火紅的嫁衣襯著肌膚如雪丛楚。 梳的紋絲不亂的頭發(fā)上族壳,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天憔辫,我揣著相機(jī)與錄音,去河邊找鬼仿荆。 笑死贰您,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的拢操。 我是一名探鬼主播锦亦,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼令境!你這毒婦竟也來(lái)了杠园?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤舔庶,失蹤者是張志新(化名)和其女友劉穎抛蚁,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體惕橙,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瞧甩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了弥鹦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肚逸。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖彬坏,靈堂內(nèi)的尸體忽然破棺而出朦促,到底是詐尸還是另有隱情,我是刑警寧澤栓始,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布务冕,位于F島的核電站,受9級(jí)特大地震影響混滔,放射性物質(zhì)發(fā)生泄漏洒疚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一坯屿、第九天 我趴在偏房一處隱蔽的房頂上張望油湖。 院中可真熱鬧,春花似錦领跛、人聲如沸乏德。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)喊括。三九已至胧瓜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間郑什,已是汗流浹背府喳。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蘑拯,地道東北人钝满。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像申窘,于是被迫代替她去往敵國(guó)和親弯蚜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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