九、ajax技术

1.Ajax

Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。

1.1.为什么会出现Ajax技术?

因为传统的网页技术,存在诸多不足,每次页面要进行刷新时,需要重新加载整个页面,这样会导致浏览器需要重新解析所有的页面数据,页面中原有的数据,不需要重新解析渲染的也会丢失,服务器,也需要构建整个页面的数据。这样增加了服务器,带宽,浏览器的压力,且用户体验比较差,因为数据的更新是无差别的,需要更新的或者不需要更新的,整个网页数据都会更新。这样可能导致用户的某些不需要更新的行为数据,没重置了,用户需要重新输入且用户不知道被刷新的原因。基于这点,需要根据需求,可选的改变网页上的数据.这种改变网页上的数据,是只改变网页上的部分数据,这样做,服务器需要构建的数据,相对少,传输的数据也少,浏览重新解析渲染的压力也小。这种方法就被称之为局部刷新

传统网页交互的不足.png

1.2.Ajax技术的原理

为了弥补传统的不足,需要可选的改变网页部分数据,而改变网页的数据的依据需要从服务器获取,那么浏览器就需要与服务器交互。就是浏览器需要发送请求给服务器,但是浏览器没办法可选的修改网页数据,网页数据属于DOM元素,需要使用网页脚本语言进行修改。所以基于这点,开发者让浏览器厂商提供了发送请求的API,通过Javascript,利用浏览器向服务器发送请求,且接收服务器的响应数据,然后根据响应作为更新页面的依据。从而实现了页面局部刷新的效果,这种技术就是Ajax技术。由于,此时浏览器与服务器的交互是在后台的进行交互的,所以这种交互方式也被称之为异步交互Ajax技术就是一种异步交互。其原理,本质上就是Javascript利用浏览器,在后台与服务交互数据,然后根据,利用Javascript的DOM的API,进行页面更新。

1.3.如何使用Ajax技术?

一般Ajax技术分为原生的Ajax技术或者第三方封装的Ajax技术。

原生的Ajax是指使用Javascript最原始的API与服务器进行交互。

原生Ajax:

XMLHttpRequest:是浏览器内置用于发送请求的对象,用于在后台与服务器交换数据。

注意:

  1. 所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象。

    使用:new XMLHttpRequest();

  2. 老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象:

    使用: new ActiveXObject("Microsoft.XMLHTTP");

以上说明XMLHttpRequest对象存在浏览器的兼容性问题.

核心方法:

方法 描述
open(method,url,async) 规定请求的类型、URL 以及是否异步处理请求。
method:请求的类型;GET 或 POST
url:文件在服务器上的位置
async:true(异步)或 false(同步)
send(string) 将请求发送到服务器。string:仅用于 POST 请求
setRequestHeader(header,value) 向请求添加 HTTP 头。
header: 规定头的名称
value: 规定头的值

事件:

onreadystatechange : 当浏览器与服务器的通信状态发生变化时就会触发该事件。

属性:

属性 描述
onreadystatechange 存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。
readyState 存有 XMLHttpRequest 的状态。
从 0 到 4 发生变化。
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪
status 200: "OK"
404: 未找到页面

响应属性:

根据以下属性,可以从请求中获取服务器响应的数据

属性 描述
responseText 获得字符串形式的响应数据。
responseXML 获得 XML 形式的响应数据。

注意:

ajax的响应数据只能是responseText或者responseXML,即Ajax的响应数据只能是字符串。

1.3.1.原生Ajax的使用

  1. 创建发送请求的对象
  2. 监听请求对象状态
    1. 根据状态解析响应数据
  3. 准备发送请求信息
  4. 发送请求
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>使用Ajax与服务器交互</title>
</head>
<body>

<div id="divId"></div>
<button id="btn"  onclick="sendAjax()">按钮</button>
<script type="text/javascript">
//1. 创建请求对象
var reuqest = new XMLHttpRequest();

    //发送ajax请求
    function sendAjax() {
        //2. 为对象添加监听事件
        reuqest.onreadystatechange = function() {
            console.log("状态发生了变化");
            //接收响应数据 
            //当请求正常  且 响应完成时接收
            console.log(reuqest.readyState);
            //只有当请求响应完成 且请求正常时  才接收数据
            if (reuqest.readyState == 4 && reuqest.status == 200) {
                //获取响应中的字符串数据
                var msg = reuqest.responseText;
                console.log(msg);
                document.getElementById("divId").innerText = msg;
            }
        }
        var param = "name=张三&age=18"
        //3. 准备发送请求 建立连接
        //reuqest.open("get","ajax.do?"+param,true);
        //reuqest.send(param);
        reuqest.open("post", "ajax.do?" + param, true);
        //4. 发送请求
        reuqest.send(param);
    }
</script>
</body>
</html>
package com.sxt.controller;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/ajax.do")
public class AjaxController extends HttpServlet {

    private static final long serialVersionUID = -116354998836682953L;

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置编码避免汉字乱码
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("charset=UTF-8");
        //接收ajax 参数
        String name = req.getParameter("name");
        String age = req.getParameter("age");
        System.out.println(name+"   "+age);
        System.out.println("有人请求了!!");
        //向ajax返回数据
        PrintWriter writer = resp.getWriter();
        //注意  使用print  不要使用println
        writer.print("请求成功");
        writer.flush();
    }
    
}

1.3.2.jquery中的ajax

由于原生ajax的API使用相对繁琐,且对浏览器的兼容性相对较差。基于这个原因,jquery插件,对原生ajax的API进行了二次封装,降低了ajax使用的难度,简化了ajax开发的步骤。

在jquery中,ajax提供如下核心方法:

方法名 说明
ajax(option) 就是进行ajax请求,最接近原生ajax的方法
post(option) 只支持post请求的ajax方法
get(option) 只支持get请求的ajax方法
load(option) 将ajax请求的数据加载到dom中

jquery中Ajax相关函数

函数 描述
jQuery.ajax() 执行异步 HTTP (Ajax) 请求。
.ajaxComplete() 当 Ajax 请求完成时注册要调用的处理程序。这是一个 Ajax 事件。与具体的ajax中complete一致
.ajaxError() 当 Ajax 请求完成且出现错误时注册要调用的处理程序。这是一个 Ajax 事件。与具体的error一致
.ajaxSend() 在 Ajax 请求发送之前显示一条消息。与具体的ajax请求中beforeSend一致
jQuery.ajaxSetup() 设置将来的 Ajax 请求的默认值。进行全局设置,所有ajax的操作,都会遵循该设置
.ajaxStart() 当首个 Ajax 请求完成开始时注册要调用的处理程序。这是一个 Ajax 事件。
.ajaxStop() 当所有 Ajax 请求完成时注册要调用的处理程序。这是一个 Ajax 事件。
.ajaxSuccess() 当 Ajax 请求成功完成时显示一条消息。
jQuery.get() 使用 HTTP GET 请求从服务器加载数据。
jQuery.getJSON() 使用 HTTP GET 请求从服务器加载 JSON 编码数据。
jQuery.getScript() 使用 HTTP GET 请求从服务器加载 JavaScript 文件,然后执行该文件。
.load() 从服务器加载数据,然后把返回到 HTML 放入匹配元素。
jQuery.param() 创建数组或对象的序列化表示,适合在 URL 查询字符串或 Ajax 请求中使用。
jQuery.post() 使用 HTTP POST 请求从服务器加载数据。
.serialize() 将表单内容序列化为字符串。
.serializeArray() 序列化表单元素,返回 JSON 数据结构数据。

option:ajax请求的相关参数

参数名 值类型 说明
async Boolean 默认值: true。默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false。
beforeSend Function 发送请求前可修改 XMLHttpRequest 对象的函数,如添加自定义 HTTP 头。
cache Boolean 默认值: true,dataType 为 script 和 jsonp 时默认为 false。设置为 false 将不缓存此页面。
complete Function 请求完成后回调函数 (请求成功或失败之后均调用)。
contentType String 默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。
context Object 这个对象用于设置 Ajax 相关回调函数的上下文。
data String 发送到服务器的数据。
dataFilter Function 给 Ajax 返回的原始数据的进行预处理的函数。提供 data 和 type 两个参数:data 是 Ajax 返回的原始数据,type 是调用 jQuery.ajax 时提供的 dataType 参数。函数返回的值将由 jQuery 进一步处理。
dataType String 预期服务器返回的数据类型.
"xml": 返回 XML 文档
"html": 返回纯文本 HTML 信息
"script": 返回纯文本 JavaScript 代码。
"json": 返回 JSON 数据 。
"jsonp": JSONP 格式。
"text": 返回纯文本字符串
error Function 有以下三个参数:XMLHttpRequest 对象、错误信息、(可选)捕获的异常对象。当ajax发生错误时调用
global Boolean 是否触发全局 AJAX 事件。默认值: true。
success Function 请求成功后的回调函数。参数:由服务器返回,并根据 dataType 参数进行处理后的数据;
timeout Number 设置请求超时时间(毫秒)。
type String 提交方式 GET POST DELETE PUT 等等
url String 默认值: 当前页地址。发送请求的地址。

API示例1:ajax基本请求参数

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jquery-ajax配置项API</title>
</head>
<body>

<button id="btn1">jquery最基本的ajax请求</button>

<script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
    //为按钮绑定事件
    $("#btn1").click(function(){
        //请求的配置项   请求的参数
        var option = {
            url:"ajax.do",//请求的URL地址
            type:"get",//请求方法
            data:{'name':'韩梅梅','age':18}, //请求参数
            timeout:5000, //请求超时时间  单位毫秒 如果超出这个时间 则终止请求 触发error函数
            error:function(req,msg,exception){//请求出现异常时调用的方法
                console.log(req);
                console.log(msg);
                console.log(exception);
            },
            success:function(rs){//请求成功时调用的方法   响应码是  200
                console.log("返回的数据是:"+rs);
            },
            complete:function(req,msg){//每次请求完成都会调用  不论成功还是失败
                console.log("complete:"+req);
                console.log("complete:"+msg);
            }
        };
        //进行ajax请求
        $.ajax(option);
    });
</script>
</body>
</html>

AJax请求相关参数: 非常用参数

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jquery-ajax配置项API</title>
</head>
<body >

<button id="btn1">jquery最基本的ajax请求</button><br>
<button id="btn2">jquery最非常用属性介</button>


<img src="img/loading.gif" id="loading" style="width: 100px;height: 100px;display: none" />

<script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
    //jquery ajax 非常用属性介绍
    $("#btn2").click(function(){
        var option = {
            url:"ajax.do",
            type:"get",
            async:true,// 是否进行异步请求  默认是 true 如果需要同步请求 则为false
            //如果ajax是异步请求,那么不管ajax相关代码是否执行完,ajax之后的代码都会执行
            //如果ajax是同步请求,那么只有当ajax相关代码执行完,ajax之后的代码才会执行
            //如果ajax相关数据 参与ajax之后的代码运算,建议使用同步请求
            beforeSend:function(XHR){//进行ajax请求前调用的函数 此时 只属于当前ajax请求
                //设置请求头
                $("#loading").show();
            },
            context:document.body,// 指定ajax中的this 对象
            dataType:"json",// ajax 期望的返回数据的格式类型  如果返回的数据  无法转化为期望格式类型,程序会报错 ,chrome看不到
            dataFilter:function(data,type){//为ajax 返回的原始数据进行预处理的函数  
                //根据 type 的值  将data 原始数据进行预处理
                //原始数据都默认普通字符串 将字符串转化为json对象
                //data  内容 : 请求成功    普通字符串
                console.log(data);
                console.log(type);
                var obj = new Object();
                if(type == "json"){
                    obj.msg = data;
                }
                //此时打印的是js 对象
                console.log(obj); //现在js 对象  根json 规范一样
                //转化为json 对象
                //将 js 对象转化为 json 对象
                var jsonObj = $.parseJSON('{"msg":"请求成功"}');
                //此时打印的json 对象
                //console.log(jsonObj);
                
                return  JSON.stringify(jsonObj); 
                // 拼接成了  json 字符串  jquery 对这个字符串进行转化
                //然后 转化后的结果 返回 success 方法 当做参数
                
            },
            success:function(rs){//请求成功时调用的方法   响应码是  200
                //rs.msg   ---- rs 是一个对象 
                
                
                console.log("返回的数据是:"+rs.msg);
                
            
            //例如: success 里面做了多个dom的操作   根据数据生成dom
                //而ajax 之后代码有相关关联的dom操作,则容易程序异常问题
                $(this).attr("bgcolor","red");
            },
            complete:function(req,msg){//每次请求完成都会调用  不论成功还是失败
                $("#loading").hide();
            }
        };
        //进行ajax请求
        $.ajax(option);
        //进行dom 相关操作    获取 success 生成的dom
    })
</script>
</body>
</html>

Ajax中的方法示例

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jquery ajax 中的方法介绍</title>
</head>
<body>
<form id="form1">
    名称:<input name="name"/><br>
    年龄:<input name="age" />
    <input type="button" id="subBtn1" value="提交" />
</form>
<img src="img/loading.gif" id="loading" style="width: 100px;height: 100px;display: none" />
<button id="btn1" >获取表单数据</button>
<button id="btn2" >get发送ajax请求</button>
<button id="btn3" >post发送ajax请求</button>
<button id="btn4" >getJSON</button>
<button id="btn5" >load</button><br>
<h1>ajax2.html中</h1>
<div id="content"></div>

<script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
    //ajax 的全局设置
    //只要进行了全局设置  所有的 ajax 请求都会触发相关设置的方法
    /* $.ajaxSetup({
        beforeSend:function(req){
            // 在 前端后分离的项目中  此时可以在beforeSend中统一设置请求头
            console.log("请求前");
        },
        dataFilter:function(data,type){
            //统一进行数据拦截 
            //例如 : 如果数据不符合规范  则 进行某些业务处理
        },
        complete:function(req,rs){
            console.log("请求完成");
        }
    }); */
    //获取表单数据  便于 ajax 进行提交
    $("#btn1").click(function(){
        $(document).ajaxStart(function(){
            console.log("ajax 开始请求");
        });
        $(document).ajaxStop(function(){
            console.log("ajax 结束请求");
        });
        //获取表单中数据  序列化为表单格式的字符串
        var data = $("#form1").serialize();
        console.log(data);
        data = $("#form1").serializeArray();
        console.log(data);
        
        $.ajax({
            url:"ajax.do",
            success:function(rs){
                console.log(rs);
            }
        });
    });
    // ajax 中  get  和 post 
    //为了简化 ajax 开发  jquery 提供了  get 和 post 两个方法
    //这两个方法
    /*  
        url : 请求地址
        param : 请求参数
        function(rs){}: 请求成功后的回调函数
        $.get(url,param,function(rs){});
        
        $.post(url,param,function(rs){});
        get 和 post 方法中的ajax 配置都使用的是默认配置
        
        注意: 使用  get 和  post 获取的ajax 数据 是原始数据  数据类型由服务器决定  jquery 不会对数据做处理
    */
    //使用 get 方法 发送ajax 请求   
    $("#btn2").click(function(){
        $.get("ajax.do",{'name':'韩梅梅','age':18},function(rs){
            console.log(rs);
        });
    });
    //使用post 方法 发送ajax请求
    $("#btn3").click(function(){
        $.post("ajax.do",{'name':'李磊','age':18},function(rs){
            console.log(rs);
        });
    }); 
    //获取json 格式数据  getJSON 指定返回的数据类型是json类型
    $("#btn4").click(function(){
        $.getJSON("json.do",function(rs){
            console.log(rs);
        });
    }); 
    //.load() 从服务器加载数据,然后把返回到 HTML 放入匹配元素。
    $("#btn5").click(function(){
        $("#content").load("load.do");
    }); 

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

注意:

  1. 在jQuery 1.9后,全局Ajax事件(ajaxStart, ajaxStop, ajaxSend, ajaxComplete, ajaxError, ajaxSuccess)只在document节点上触发.

    只能:$(document).ajaxStart(...)

  2. 在javascript中:

    1. 将json字符串转化为json对象:JSON.parse(str) 或者 $.parseJSON(str) evel
    2. 将对象转化为JSON字符串 :JSON.stringify(obj)

1.4.案例

1.4.1.ajax登录案例

  1. 使用js获取表单数据
  2. 服务器获取ajax提交的数据根据数据做出相应的响应数据
  3. js获取响应数据,做出相应的反映
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<!-- 此时使用ajax  form中 无需指定action  method 等等 -->
<form >
    <p>用户名:<input type="text" id="userName" name="userName" /> </p>
    <p>密码:<input type="text" id="password" name="password" /></p>
    <p><span id="errorInfo" style="color:red"></span></p>
    <!-- 此时 提交表单数据  使用 js提交  所以 一定不要使用submit -->
    <input type="button" value="提交" id="subBtn"/>
</form>
<script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
    $("#subBtn").click(function(){
        var userName = $("#userName").val();
        if(userName == null || userName == ''){
            $("#errorInfo").text("用户名不能为空");
            //阻止后面的js 执行
            return false;
        }
        var password = $("#password").val();
        if(password == null || password == ''){
            $("#errorInfo").text("密码不能为空");
            //阻止后面的js 执行
            return false;
        }
        var param = {
            'service':'login',
            'userName':userName,
            'password':password
        };
        //提交数据给服务器
        $.post("user.do",param,function(rs){
            //对rs 响应数据进行解析
            //如果rs 表示是成功  则 可以跳转到 登录成功的页面
            //如果rs 表示是失败  则 将失败原因 显示在页面
            // 服务器中返回的数据  code值为 200 时 才表示正常 
            // 如果不是200  表示都是异常的   msg  就是异常的原因
            //协议  服务器返回的数据的协议
            console.log(rs);
            if(rs.code != 200){
                $("#errorInfo").text(rs.msg);
                return false;
            }
            //如果 code 值为 200  说明 用户名和密码是正确 进行页面跳转
            //需要使用 js 实现  页面跳转
            location.href = "success.html";
            
        });
    });

</script>
</body>
</html>
package com.sxt.controller;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
@WebServlet("/user.do")
public class UserController extends HttpServlet {

    private static final long serialVersionUID = 7723086583204133716L;

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String  service = req.getParameter("service");
        if("login".equals(service)) {
            login(req,resp);
        }
    }
    /**
     * @Title: login
     * @author: Mr.T   
     * @date: 2020年2月19日 下午5:42:20 
     * @Description: 处理登录业务的方法
     * @param req
     * @param resp
     * @return: void
     * @throws IOException 
     */
    private void login(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String userName = req.getParameter("userName");
        String password = req.getParameter("password");
        JSONObject rs = new JSONObject();
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("json/text;charset=UTF-8");
        PrintWriter writer = resp.getWriter();
        //校验用户名   告诉浏览器  用户名错误
        if(!"admin".equals(userName)) {
            //业务错误码
            rs.put("code", 4001);
            //业务错消息
            rs.put("msg","用户名错误");
            //将结果数据返回给浏览器
            writer.write(rs.toJSONString());
            writer.flush();
            writer.close();
            return;
        }
        // 校验密码
        if (!"admin".equals(password)) {
            // 业务错误码
            rs.put("code", 4002);
            // 业务错消息
            rs.put("msg", "用户密码错误");
            // 将结果数据返回给浏览器
            writer.write(rs.toJSONString());
            writer.flush();
            writer.close();
            return;
        }
        // 业务错误码
        rs.put("code", 200);
        // 业务错消息
        rs.put("msg", "登录成功");
        // 将结果数据返回给浏览器
        writer.write(rs.toJSONString());
        writer.flush();
        writer.close();
        return;
    }

    
    
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容