使用flask快速擼一個(gè)http在線請(qǐng)求工具

好久沒有使用python flask 框架了,今天有個(gè)想法技即,就是打造自己的一個(gè)在線http請(qǐng)求工具,網(wǎng)上有很多這樣的工具晌柬,寫這個(gè)東西本身沒有太多的技術(shù)含量姥份,純粹是為了學(xué)習(xí),順便鞏固一下flask年碘。
話不多說先看效果


image.png

image.png

image.png

看上去很簡單,覺得就是個(gè)表單提交展鸡,實(shí)際上呢屿衅,也是需要一點(diǎn)處理邏輯的,麻雀雖小莹弊,五張俱全嘛涤久。因?yàn)檫@個(gè)demo不需要數(shù)據(jù)庫涡尘,也不需要管理,所以响迂,采用flask開發(fā)在合適不過了考抄。廢話說完了,開始擼碼蔗彤,真刀真槍開始干川梅。

實(shí)現(xiàn)思路: 前端使用ajax提交表單到后臺(tái),后臺(tái)通過requests 進(jìn)行http請(qǐng)求并返回結(jié)果然遏,然后將結(jié)果返回給前端進(jìn)行展示贫途,就是這么簡單。

第一步:環(huán)境準(zhǔn)備:
1.python3.x
2.flask web框架
3.requests http請(qǐng)求框架
4.bootstrap 框架(界面)
5.pycharm 開發(fā)工具

第二步: 基本項(xiàng)目搭建
1.用pycharm新建一個(gè)flask項(xiàng)目待侵,然后跑起來丢早,這一步是為了驗(yàn)證項(xiàng)目是否有問題。
2.在項(xiàng)目的templates目錄新建一個(gè)html文件秧倾,然后修改flask后臺(tái)代碼返回新建的html模版看能否正常顯示

from flask import render_template 
@app.route('/')
def home():
    return render_template('index.html')

3.修改html文件,引入bootstrap,完成基本的頁面布局

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>http在線工具</title>

    <!-- 新 Bootstrap 核心 CSS 文件 -->
<link  rel="stylesheet">

<!-- jQuery文件怨酝。務(wù)必在bootstrap.min.js 之前引入 -->
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>

<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>

<div class="col-sm-12" style="margin-top: 20px">

   <div class="col-sm-6">
    <form role="form">
  <div class="form-group">
    <label for="name">請(qǐng)求地址:</label>
    <input type="text" class="form-control" id="url" placeholder="http://或https://">
  </div>
   <div class="form-group">
    <label for="name">請(qǐng)求方式:</label>
    <select class="form-control" id="method">
      <option value="get" selected>get</option>
      <option value="post">post</option>
    </select>
  </div>
     <div class="form-group">
    <label for="name">請(qǐng)求頭信息:</label>
    <textarea class="form-control" id="headers" rows="3" placeholder="如:token:xxxx,a:xx多個(gè)參數(shù)用,隔開"></textarea>
  </div>
     <div class="form-group">
      <label for="name">請(qǐng)求參數(shù):</label>
    <textarea class="form-control" rows="3" id="params" placeholder="如:a=1&b=2"></textarea>
  </div>

        <button  id="btn" class="btn btn-primary" data-loading-text="Loading..."
    type="button"> 提交
</button>
</form>
</div>


<div class="col-sm-6">

    <ul class="nav nav-tabs" id="tabs">
  <li class="active"><a href="#">格式化響應(yīng)</a></li>
  <li><a href="#">原始響應(yīng)</a></li>
  <li><a href="#">響應(yīng)頭信息</a></li>

</ul>

 <textarea id="result" style="margin-top: 10px;overflow: scroll;padding:10px;background-color:cornsilk;width: 100%;height: 350px">

 </textarea>
</div>
</div>
   
</body>
</html>

4.重新啟動(dòng)項(xiàng)目看看界面效果是否正常,沒有問題那先。
5.在app.py里新增一個(gè)函數(shù)用戶接收前端發(fā)來的參數(shù)

@app.route("/http", methods=['post'])
def http_request():
return "請(qǐng)求成功"

6.在前端頁面用jquery進(jìn)行ajax請(qǐng)求:

  $.ajax(({
            url:'/http',
            method:'post',
            success:function(data){
                alert(data)

            },
            error:function (e) {
            
                alert("請(qǐng)求地址異常")
            }
        }))

如果可以正常的請(qǐng)求农猬,基本的環(huán)境就搭建完成了。

第三步,邏輯的實(shí)現(xiàn):
1.分析前端需要傳哪些參數(shù)到后臺(tái)胃榕,首先請(qǐng)求地址url盛险、然后請(qǐng)求方式,method勋又,還是請(qǐng)求頭信息headers和請(qǐng)求參數(shù)信息params苦掘。前端獲取輸入的這些值,基礎(chǔ)的就不多說了楔壤。
2.ajax請(qǐng)求添加這些參數(shù)

    $.ajax({

            url:'/http',
            method:'post',
            data:{url:url,method:method,headers:headers,params:params},
            success:function(data){
  
                response = data.body;
                header = data.header;
                show(response);

            },
            error:function (e) {
    
                alert("請(qǐng)求地址異常")
            }

        })
  1. 修改后臺(tái)函數(shù)后臺(tái)進(jìn)行參數(shù)接收:
@app.route("/http", methods=['post'])
def http_request():
    url = request.form['url']
    print('----url----',url)
    method = request.form['method']
    print('----method----',method)
    headers = request.form['headers']
    print('----headers----',headers)
    params = request.form['params']
    print('----params----',params)
    return "請(qǐng)求成功"

在前端提交看看后臺(tái)能不能收到這些參數(shù),如果不會(huì)flask參數(shù)接收自行到網(wǎng)上搜索一下鹤啡。收到了參數(shù)就進(jìn)行下一步。

4.處理接收到的參數(shù)蹲嚣,因?yàn)閞equests需要的參數(shù)不是字符串递瑰,所以需要轉(zhuǎn)換成一個(gè)字典。第一個(gè)就是處理請(qǐng)求頭信息隙畜,新增一個(gè)函數(shù)用戶處理頭信息:

def parse_headers(headers):
    args = {}
    if headers:
        sps = headers.split(',')
        for s in sps:
            p = s.split(":")
            print(p[0], "=", p[1])
            args[p[0]] = p[1]

    return args

這里需要前段端和后臺(tái)的參數(shù)約束抖部,比如:多個(gè)參數(shù)用,號(hào)隔開,鍵和值之間用:,處理完成返回一個(gè)字典。

第二個(gè)就是處理請(qǐng)求參數(shù)的函數(shù):

def parse_params(params):
    args = {}
    if params:
        sps = params.split('&')
        for s in sps:
            p = s.split("=")
            print(p[0], "=", p[1])
            args[p[0]] = p[1]

    return args

和請(qǐng)求頭信息處理類似议惰,只是約束不一樣慎颗,我們多個(gè)參數(shù)使用&鏈接,鍵和值用=號(hào)。

5.使用requests進(jìn)行http請(qǐng)求,一般都是使用

import requests
一般都是使用
requests.get()和requests.post;

但是為了統(tǒng)一采用以下方式進(jìn)行請(qǐng)求俯萎,不清楚的可以看requests的相關(guān)文檔:

from requests import Session, Request
# 統(tǒng)一發(fā)起http請(qǐng)求
def send(url, method, headers, data):
    s = Session()
    req = Request(method, url,
                  data=data,
                  params=data,
                  headers=headers
                  )
    prepped = req.prepare()
    resp = s.send(prepped)
    try:
        res = {"header": "{0}".format(resp.headers), "body": "{0}".format(resp.content.decode(encoding='utf-8'))}
        return Response(json.dumps(res), mimetype='application/json')
    except:
        res = {"header": "{0}".format(resp.headers), "body": "{0}".format(resp.content)}
        return Response(json.dumps(res), mimetype='application/json')

這里面有個(gè)data和params參數(shù)傲宜,說明一下,為什么要傳兩個(gè)夫啊,data參數(shù)是針對(duì)post請(qǐng)求的params是get請(qǐng)求函卒,因?yàn)檫@里的請(qǐng)求既支持get也支持post請(qǐng)求,這兩個(gè)參數(shù)都傳是為了保證post和get請(qǐng)求都能把參數(shù)傳輸過去撇眯。請(qǐng)求成功后报嵌,返回json給前端。我們要返回headr和body,因?yàn)榍岸诵枰故菊?qǐng)求頭信息和請(qǐng)求內(nèi)容叛本。這里需要注意的是得到的header信息和請(qǐng)求的content信息不能直接被序列化沪蓬,所以需要轉(zhuǎn)換成字符串在以json的格式輸出,否則就會(huì)報(bào)錯(cuò)来候,因?yàn)檗D(zhuǎn)了字符串跷叉,導(dǎo)致編碼問題,所以需要用decode解碼营搅,但是解碼的時(shí)候有些內(nèi)容不支持utf-8云挟,會(huì)產(chǎn)生異常,因此需要進(jìn)行異常處理转质,保證把結(jié)果返回园欣。

  1. 后臺(tái)調(diào)用:修改http_request函數(shù)
@app.route("/http", methods=['post'])
def http_request():
    url = request.form['url']
    method = request.form['method']
    headers = parse_headers(request.form['headers'])
    params = request.form['params']
    args = parse_params(params)

    return send(url, method, headers, args)

當(dāng)然,還有需要完善的地方休蟹,比如參數(shù)校驗(yàn)沸枯,我就偷懶不處理了??。

7.前端的展示

     $.ajax({

            url:'/http',
            method:'post',
            data:{url:url,method:method,headers:headers,params:params},
            success:function(data){
        
                response = data.body;
                header = data.header;
                show(response);

            },
            error:function (e) {
         
                alert("請(qǐng)求地址異常")
            }

        })

    //tab切換
     $('#tabs li').click(function () {


          $.each($('#tabs li'),function (i,item) {
                item.className = '';
          })

          this.className = 'active';


         switch ($(this).index()) {

             case 0:
                 //展示格式化結(jié)果
                  show(response)
                 break;
             case 1:
                 //展示原始結(jié)果
                   $('#result').val(response);
                 break;

             case 2:
                 //展示響應(yīng)頭信息
                  show(header)
                 break;

         }


     })

      //展示請(qǐng)求結(jié)果
       function show(data) {

          try{
                 var json = formatJson(data)
                     $('#result').val(json);
                }catch (e) {

                   $('#result').val(data);
                }
       }
       //格式化json
       function formatJson(json, options) {
                    var reg = null,
                        formatted = '',
                        pad = 0,
                        PADDING = '    '; // one can also use '\t' or a different number of spaces
                    // optional settings
                    options = options || {};
                    // remove newline where '{' or '[' follows ':'
                    options.newlineAfterColonIfBeforeBraceOrBracket = (options.newlineAfterColonIfBeforeBraceOrBracket === true) ? true : false;
                    // use a space after a colon
                    options.spaceAfterColon = (options.spaceAfterColon === false) ? false : true;

                    // begin formatting...

                    // make sure we start with the JSON as a string
                    if (typeof json !== 'string') {
                        json = JSON.stringify(json);
                    }
                    // parse and stringify in order to remove extra whitespace
                    json = JSON.parse(json);
                    json = JSON.stringify(json);

                    // add newline before and after curly braces
                    reg = /([\{\}])/g;
                    json = json.replace(reg, '\r\n$1\r\n');

                    // add newline before and after square brackets
                    reg = /([\[\]])/g;
                    json = json.replace(reg, '\r\n$1\r\n');

                    // add newline after comma
                    reg = /(\,)/g;
                    json = json.replace(reg, '$1\r\n');

                    // remove multiple newlines
                    reg = /(\r\n\r\n)/g;
                    json = json.replace(reg, '\r\n');

                    // remove newlines before commas
                    reg = /\r\n\,/g;
                    json = json.replace(reg, ',');

                    // optional formatting...
                    if (!options.newlineAfterColonIfBeforeBraceOrBracket) {
                        reg = /\:\r\n\{/g;
                        json = json.replace(reg, ':{');
                        reg = /\:\r\n\[/g;
                        json = json.replace(reg, ':[');
                    }
                    if (options.spaceAfterColon) {
                        reg = /\:/g;
                        json = json.replace(reg, ': ');
                    }

                    $.each(json.split('\r\n'), function(index, node) {
                        var i = 0,
                            indent = 0,
                            padding = '';

                        if (node.match(/\{$/) || node.match(/\[$/)) {
                            indent = 1;
                        } else if (node.match(/\}/) || node.match(/\]/)) {
                            if (pad !== 0) {
                                pad -= 1;
                            }
                        } else {
                            indent = 0;
                        }

                        for (i = 0; i < pad; i++) {
                            padding += PADDING;
                        }
                        formatted += padding + node + '\r\n';
                        pad += indent;
                    });
                    return formatted;
                };

這里需要注意赂弓,結(jié)果的展示不要使用div绑榴,就使用textarea,不然josn格式化不會(huì)有效果盈魁。

第四步:測(cè)試
萬事具備了翔怎,就來測(cè)試一把,如果有什么錯(cuò)誤就調(diào)試一下代碼了杨耙。

下面貼一下完整代碼:前端,html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>http在線工具</title>

    <!-- 新 Bootstrap 核心 CSS 文件 -->
<link  rel="stylesheet">

<!-- jQuery文件赤套。務(wù)必在bootstrap.min.js 之前引入 -->
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>

<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>

<div class="col-sm-12" style="margin-top: 20px">

   <div class="col-sm-6">
    <form role="form">
  <div class="form-group">
    <label for="name">請(qǐng)求地址:</label>
    <input type="text" class="form-control" id="url" placeholder="http://或https://">
  </div>
   <div class="form-group">
    <label for="name">請(qǐng)求方式:</label>
    <select class="form-control" id="method">
      <option value="get" selected>get</option>
      <option value="post">post</option>
    </select>
  </div>
     <div class="form-group">
    <label for="name">請(qǐng)求頭信息:</label>
    <textarea class="form-control" id="headers" rows="3" placeholder="如:token:xxxx,a:xx多個(gè)參數(shù)用,隔開"></textarea>
  </div>
     <div class="form-group">
      <label for="name">請(qǐng)求參數(shù):</label>
    <textarea class="form-control" rows="3" id="params" placeholder="如:a=1&b=2"></textarea>
  </div>
 
        <button  id="btn" class="btn btn-primary" data-loading-text="Loading..."
    type="button"> 提交
</button>
</form>
</div>


<div class="col-sm-6">

    <ul class="nav nav-tabs" id="tabs">
  <li class="active"><a href="#">格式化響應(yīng)</a></li>
  <li><a href="#">原始響應(yīng)</a></li>
  <li><a href="#">響應(yīng)頭信息</a></li>

</ul>

 <textarea id="result" style="margin-top: 10px;overflow: scroll;padding:10px;background-color:cornsilk;width: 100%;height: 350px">

 </textarea>



</div>
</div>


<script>

     var method = 'get';
     var response='';
     var header = '';
    $('#method').change(function () {

        method=$("#method").val();

    })

    $('#btn').click(function () {

        var url = $('#url').val();
        var headers = $('#headers').val();
        var params = $('#params').val();

        if(url==null||url.length==0){

            alert("請(qǐng)求地址不能為空")
            return;
        }
        if(!url.startsWith("http://")&&!url.startsWith("https://")){

            alert("請(qǐng)求地址有誤")
            return;
        }
        $(this).button('loading');

        $.ajax({

            url:'/http',
            method:'post',
            data:{url:url,method:method,headers:headers,params:params},
            success:function(data){
                $('#btn').button('reset');
                response = data.body;
                header = data.header;
                show(response);

            },
            error:function (e) {
               $('#btn').button('reset');
                alert("請(qǐng)求地址異常")
            }

        })


    })


     //tab切換
     $('#tabs li').click(function () {


          $.each($('#tabs li'),function (i,item) {
                item.className = '';
          })

          this.className = 'active';


         switch ($(this).index()) {

             case 0:
                 //展示格式化結(jié)果
                  show(response)
                 break;
             case 1:
                 //展示原始結(jié)果
                   $('#result').val(response);
                 break;

             case 2:
                 //展示響應(yīng)頭信息
                  show(header)
                 break;

         }


     })

      //展示請(qǐng)求結(jié)果
       function show(data) {

          try{
                 var json = formatJson(data)
                     $('#result').val(json);
                }catch (e) {

                   $('#result').val(data);
                }
       }
       //格式化json
       function formatJson(json, options) {
                    var reg = null,
                        formatted = '',
                        pad = 0,
                        PADDING = '    '; // one can also use '\t' or a different number of spaces
                    // optional settings
                    options = options || {};
                    // remove newline where '{' or '[' follows ':'
                    options.newlineAfterColonIfBeforeBraceOrBracket = (options.newlineAfterColonIfBeforeBraceOrBracket === true) ? true : false;
                    // use a space after a colon
                    options.spaceAfterColon = (options.spaceAfterColon === false) ? false : true;

                    // begin formatting...

                    // make sure we start with the JSON as a string
                    if (typeof json !== 'string') {
                        json = JSON.stringify(json);
                    }
                    // parse and stringify in order to remove extra whitespace
                    json = JSON.parse(json);
                    json = JSON.stringify(json);

                    // add newline before and after curly braces
                    reg = /([\{\}])/g;
                    json = json.replace(reg, '\r\n$1\r\n');

                    // add newline before and after square brackets
                    reg = /([\[\]])/g;
                    json = json.replace(reg, '\r\n$1\r\n');

                    // add newline after comma
                    reg = /(\,)/g;
                    json = json.replace(reg, '$1\r\n');

                    // remove multiple newlines
                    reg = /(\r\n\r\n)/g;
                    json = json.replace(reg, '\r\n');

                    // remove newlines before commas
                    reg = /\r\n\,/g;
                    json = json.replace(reg, ',');

                    // optional formatting...
                    if (!options.newlineAfterColonIfBeforeBraceOrBracket) {
                        reg = /\:\r\n\{/g;
                        json = json.replace(reg, ':{');
                        reg = /\:\r\n\[/g;
                        json = json.replace(reg, ':[');
                    }
                    if (options.spaceAfterColon) {
                        reg = /\:/g;
                        json = json.replace(reg, ': ');
                    }

                    $.each(json.split('\r\n'), function(index, node) {
                        var i = 0,
                            indent = 0,
                            padding = '';

                        if (node.match(/\{$/) || node.match(/\[$/)) {
                            indent = 1;
                        } else if (node.match(/\}/) || node.match(/\]/)) {
                            if (pad !== 0) {
                                pad -= 1;
                            }
                        } else {
                            indent = 0;
                        }

                        for (i = 0; i < pad; i++) {
                            padding += PADDING;
                        }
                        formatted += padding + node + '\r\n';
                        pad += indent;
                    });
                    return formatted;
                };


</script>
</body>
</html>

后臺(tái):app.py

from flask import Flask, request, Response
from flask import render_template
from requests import Session, Request
import json

app = Flask(__name__)


# 頁面展示
@app.route('/')
def home():
    return render_template('index.html')


# 處理http請(qǐng)求
@app.route("/http", methods=['post'])
def http_request():
    url = request.form['url']
    method = request.form['method']
    headers = parse_headers(request.form['headers'])
    params = request.form['params']
    args = parse_params(params)

    return send(url, method, headers, args)


# 統(tǒng)一發(fā)起http請(qǐng)求
def send(url, method, headers, data):
    s = Session()
    req = Request(method, url,
                  data=data,
                  params=data,
                  headers=headers
                  )
    prepped = req.prepare()
    resp = s.send(prepped)
    try:
        res = {"header": "{0}".format(resp.headers), "body": "{0}".format(resp.content.decode(encoding='utf-8'))}
        return Response(json.dumps(res), mimetype='application/json')
    except:
        res = {"header": "{0}".format(resp.headers), "body": "{0}".format(resp.content)}
        return Response(json.dumps(res), mimetype='application/json')


# 處理請(qǐng)求參數(shù)轉(zhuǎn)換成字典
def parse_params(params):
    args = {}
    if params:
        sps = params.split('&')
        for s in sps:
            p = s.split("=")
            print(p[0], "=", p[1])
            args[p[0]] = p[1]

    return args


# 處理請(qǐng)求頭信息轉(zhuǎn)換成字典
def parse_headers(headers):
    args = {}
    if headers:
        sps = headers.split(',')
        for s in sps:
            p = s.split(":")
            print(p[0], "=", p[1])
            args[p[0]] = p[1]

    return args


# 用于測(cè)試參數(shù)的接收和頭信息的接收
@app.route('/test', methods=['get', 'post'])
def test():
    if request.method == 'GET':
        a = request.args.get('a', '')
        b = request.args.get('b', '')
        token = request.headers.get('token')
        return '測(cè)試get請(qǐng)求,參數(shù) a={0},b={1},頭:token={2}'.format(a, b, token)

    a = request.form['a']
    b = request.form['b']
    token = request.headers.get('token')

    return '測(cè)試post請(qǐng)求,參數(shù) a={0},b={1},頭:token={2}'.format(a, b, token)


if __name__ == '__main__':
    app.run()

第五步:總結(jié)
到這里,使用flask擼一個(gè)http在線請(qǐng)求工具就完成了,當(dāng)然這只是實(shí)現(xiàn)一個(gè)模擬過程珊膜,還需要做一些細(xì)節(jié)優(yōu)化容握,廢話多了,只是想說的詳細(xì)點(diǎn)车柠。因?yàn)榇a不多我就不上傳到github了唯沮,如果有需要的可以聯(lián)系我,如果有問題歡迎留言討論脖旱,喜歡我的文章記得關(guān)注我??哦堪遂!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末介蛉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子溶褪,更是在濱河造成了極大的恐慌币旧,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猿妈,死亡現(xiàn)場離奇詭異吹菱,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)彭则,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門鳍刷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人俯抖,你說我怎么就攤上這事输瓜。” “怎么了芬萍?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵尤揣,是天一觀的道長。 經(jīng)常有香客問我柬祠,道長北戏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任漫蛔,我火速辦了婚禮嗜愈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘莽龟。我一直安慰自己蠕嫁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布轧房。 她就那樣靜靜地躺著拌阴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪奶镶。 梳的紋絲不亂的頭發(fā)上迟赃,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音厂镇,去河邊找鬼纤壁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛捺信,可吹牛的內(nèi)容都是我干的酌媒。 我是一名探鬼主播欠痴,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼秒咨!你這毒婦竟也來了喇辽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤雨席,失蹤者是張志新(化名)和其女友劉穎菩咨,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體陡厘,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡抽米,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了糙置。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片云茸。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖谤饭,靈堂內(nèi)的尸體忽然破棺而出束凑,到底是詐尸還是另有隱情徒爹,我是刑警寧澤肪康,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布竣稽,位于F島的核電站,受9級(jí)特大地震影響功舀,放射性物質(zhì)發(fā)生泄漏萍倡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一辟汰、第九天 我趴在偏房一處隱蔽的房頂上張望列敲。 院中可真熱鬧,春花似錦帖汞、人聲如沸戴而。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽所意。三九已至,卻和暖如春催首,著一層夾襖步出監(jiān)牢的瞬間扶踊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來泰國打工郎任, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留秧耗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓舶治,卻偏偏與公主長得像分井,于是被迫代替她去往敵國和親车猬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354