前端面试题系列之- HTML 及浏览器篇

1. 什么是 HTML

  • HTML 是用来描述网页的一种语言。
  • HTML 指的是超文本标记语言: HyperText Markup Language
  • HTML 不是一种编程语言,而是一种标记语言

2. DOCTYPE 是什么,都有哪些模式

  1. <!DOCTYPE> 声明位于文档中的最前面,处于 <html> 标签之前。告知浏览器的解析器,用什么文档类型 规范来解析这个文档。
  2. 严格模式的排版和 JS 运作模式是 以该浏览器支持的最高标准运行。
  3. 在混杂模式中,页面以宽松的向后兼容的方式显示。模拟老式浏览器的行为以防止站点无法工作。
  4. DOCTYPE不存在或格式不正确会导致文档以混杂模式呈现

3. 什么是 H5,H5 和 HTML 的区别是什么,你用到过哪些 H5 标签

HTML5 是对 HTML 标准的第五次修订。其主要的目标是将互联网语义化,以便更好地被人类和机器阅读,并同时提供更好地支持各种媒体的嵌入。HTML5 的语法是向后兼容的。

HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。

<header>          网页的头部
<nav>                网页的导航
<section>          标签定义文档中的节(比如章节、页眉、页脚或文档中的其他部分。)
<article>            标签的内容独立于文档的其余部分。比如外部的一篇文章,一个博客,论文
<aside>              网页侧边栏
<footer>            网页的页脚

<canvas>  通过脚本绘制图像
<Audio>    播放音频
<Video>    播放视频

4. 你是如何理解 HTML 语义化的

  • 用正确的标签做正确的事情
  • 使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解
  • 让网络爬虫更好的解析,利于 SEO 优化

5. iframe 有哪些缺点

  • iframe会阻塞主页面的onload事件
  • iframe和主页面共享连接池,而浏览器对相同域的连接有限制(6-8),所以会影响页面的并行加载
  • 使用iframe之前需要考虑这两点,如果需要使用iframe,最好通过 js 动态给 iframe 添加 src 属性

6. meta 标签的几种用法

指定文档编码

<meta charset="UTF-8">

适配移动页面

<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="viewport"  content="width=device-width,initial-scale=1.0">

添加页面描述

<meta name="description" content="腾讯网(www.qq.com)是中国最浏览量最大的门户网站">

7. cookie、session、sessionStorage 和 localStorage 的区别

cookie 和 sessionStorage、localStorage 的区别

cookie sessionStorage localStorage
生命周期 可以自己设置,默认到浏览器关闭 浏览器关闭 除非自行删除或清除,否则一直存在
大小 4K 5MB 5MB
服务器通讯 http头中 仅在客户端,不参与通讯 仅在客户端,不参与通讯
易用性 需自己封装接口 接口可直接使用 接口可直接使用
作用域 由domain字段控制,为父域名及其子域名,可跨浏览器访问 不可跨浏览器访问,只能在当前页面使用。同浏览器,同ip端口的两个页面会创建两个sessionStorage 相同浏览器,不同页面间(ip及端口一致)可以共享,不可跨浏览器访问

cookie和session的区别

  • cookie数据存放在客户的浏览器上,session数据放在服务器上
  • cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session
  • session会在一定时间内保存在服务器上,当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie
  • 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie
  • 建议将登录信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中
  • session保存在服务器,客户端不知道其中的信息;cookie保存在客户端,服务器能够知道其中的信息
  • session中保存的是对象,cookie中保存的是字符串
  • session不能区分路径,同一个用户在访问一个网站期间,所有的session在任何一个地方都可以访问到,而cookie中如果设置了路径参数,那么同一个网站中不同路径下的cookie互相是访问不到的

8. cookie 跨域问题及解决

什么是cookie跨域问题

在Cookie规范上说,一个cookie只能用于一个域名,不能够发给其它的域名。因此,如果在浏览器中对一个域名设置了一个cookie,这个cookie对于其它的域名将无效。如果你想让你的用户从你的站点中专的其中一个进行登录,同时也可以在其它域名上进行登录,这可真是一属个大难题。这就是跨域问题。

cookie 的作用域由domain字段及path字段限制。domain字段设置哪些域名可以访问cookie,一般设置 .xxx.xxx 这样 a.xxx.xxxb.xxx.xxx 都可以访问这个cookie。

网页发送的请求默认是带cookie的,ajax、fetch等默认是不带cookie的。

解决cookie 跨域的几种方法。

JSONP

通过JSONP向服务器发送GET请求,浏览器会自动在请求头中携带当前域名下的cookie信息。

缺点:

  • 只能支持GET请求
  • 只能携带本域名下的cookie
CORS

后台设置响应头

Access-Control-Allow-Credentials: true;
Access-Control-Allow-Origin: a.com; //必须为具体域名,不能是*

前端跨域携带cookie

// JS:
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.open('POST', ‘a.com’, true);
xhr.send();

// JQuery:
$.ajax({
    url: a_cross_domain_url,
    xhrFields: {
    withCredentials: true
}});

// axios
axios.defaults.withCredentials = true

// fetch

fetch(url, {credentials: 'include' })

CORS缺点是,低版本的IE浏览器支持不好。

总结

fetch ajax axios jq 表现一致。

  • 不设置 withCredentials 属性,跨域访问时,抛掉服务器响应头的 set-cookie 头,也不会携带跨域的cookie。
  • 设置 withCredentials 属性,跨域访问时,接收 set-cookie 头,并携带当前域及跨域的cookie
  • 不跨域访问而是访问当前域名时,无需设置 withCredentials 属性,自动携带当前域名下的cookie。

举例:当前域名 a.com,跨域域名 b.com


function ajaxSend(url, type) {
    var xhr = new XMLHttpRequest();
    if (type) xhr.withCredentials = true;
    xhr.open('GET', url, true);
    xhr.send();
}

function fetchSend(url, type) {
    fetch(url, {
        credentials: type ? 'include' : "same-origin"
    })
}

let urlA = "http://a.com/xxx";
let urlB = "http://b.com/xxx";

ajaxSend(urlA);  // 携带 a.com的cookie,接收a.com服务器的set-cookie
ajaxSend(urlA, true);  // 同域名下访问,withCredentials 设置没有效果,和上面保持一致,携带 a.com的cookie,接收a.com服务器的set-cookie
ajaxSend(urlB);  // 如果服务器没有设置cors,会报错,设置了cors,不报错,但是不发送cookie,不接收 set-cookie
ajaxSend(urlB, true);  // 需要服务器设置cors,接收 set-cookie,发送 a.com的cookie,也发送b.com的cookie

// 与 ajax 保持一致
fetchSend(urlA);
fetchSend(urlA, true);
fetchSend(urlB);
fetchSend(urlB, true);

9. 页面渲染机制,onload和DOMContentLoaded事件

页面加载过程

  • 浏览器根据 DNS 服务器得到域名的 IP 地址
  • 向这个 IP 的机器发送 HTTP 请求
  • 服务器收到、处理并返回 HTTP 请求
  • 浏览器得到返回内容

页面渲染

  • 解析数据生成DOM树
  • 解析css生成CSSOM树
  • 如果文档中有script标签的话会阻塞文档DOM解析,先执行script文件的加载并执行,而script标签会依赖这个标签之前的样式文件的加载。所以,如果页面中有script标签的话,会先将之前的样式文件加载后,加载并执行script标签中的脚本,之后继续执行文档DOM解析
  • 解析完成后,浏览器引擎会通过DOM Tree 和 CSS Rule Tree 来构造 Rendering Tree
  • 最后通过调用操作系统Native GUI的API绘制

DOMContentLoaded是指dom内容加载完成。当输入一个URL,页面的展示首先是空白的,然后过一会,页面会展示出内容,但是页面的有些资源比如说图片资源还无法看到,此时页面是可以正常的交互,过一段时间后,图片才完成显示在页面。从页面空白到展示出页面内容,会触发DOMContentLoaded事件。而这段时间就是HTML文档被加载和解析完成。

页面回流和重绘

回流:当render tree中的一部分(或全部)因为元素的尺寸,布局,隐藏等改变而需要重新构建,就是回流。回流后会进行重绘。

重绘:当只是元素的外观,风格变化,不影响布局的,重新渲染的过程就叫重绘。

注意:回流必将引起重绘,而重绘不一定会引起回流。

什么情况下产生回流:
  1. 添加或者删除可见的DOM元素;
  2. 元素位置改变;
  3. 元素尺寸改变——边距、填充、边框、宽度和高度
  4. 内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变;
  5. 页面渲染初始化;
  6. 浏览器窗口尺寸改变——resize事件发生时;
  7. 获取元素的偏移量属性
如何减少回流:
  1. 修改样式和添加DOM元素时,批量处理。
  2. 采用虚拟DOM技术
  3. 直接改变className修改多个属性
  4. 取offsetWidth等属性值,缓存到变量,少去取值。
  5. 将元素脱离文档流。

DOMContentLoaded的计算时间:

  • 当文档中没有脚本时,浏览器解析完文档便能触发 DOMContentLoaded 事件
  • 如果文档中包含脚本,则脚本会阻塞文档的解析,而脚本需要等位于脚本前面的css加载完才能执行
  • 在任何情况下,DOMContentLoaded 的触发不需要等待图片等其他资源加载完成

onload的计算时间

  • 页面上所有的资源(图片,音频,视频等)被加载以后才会触发load事件

js放在文件尾部和放在文件head中的区别是

  • 会影响页面渲染及First Paint 的渲染时间
  • 不会影响DOMContentLoaded被触发的事件

参考链接
DOMContentLoaded与load的区别
前端开发这么多年,你真的了解浏览器页面渲染机制吗?

10. async和defer的作用是什么?有什么区别?

  • async 异步加载,加载完成后立即执行
  • defer 异步加载,加载完成后,等待DOM加载完成后执行
  • 普通的script标签 dom加载遇到script标签后,会先加载并执行script标签的脚本,阻塞页面加载。

11. 常见浏览器内核

Trident(IE)、Gecko(火狐)、Blink(Chrome、Opera)、Webkit(Safari)。

12. title 和 alt 的区别

  • title 为鼠标放在标签上显示的内容
  • alt 为图片加载不出来显示的内容

13. 自定义元素 webcomponent,自定义属性 data-*

HTML5 增加了一项新功能是 自定义数据属性 ,也就是 data-* 自定义属性。在HTML5中我们可以使用以 data- 为前缀来设置我们需要的自定义属性,来进行一些数据的存放。

HTML5新增了个 dataset 属性来存取 data-* 自定义属性的值。这个 dataset 属性是HTML5 JavaScript API的一部分,用来返回一个所有选择元素 data- 属性的DOMStringMap对象。使用这种方法时,不是使用完整的属性名,如 data-index 来存取数据,应该去掉data- 前缀。

还有一点特别注意的是: data- 属性名如果包含了连字符,例如:data-index-color ,连字符将被去掉,并转换为驼峰式的命名,前面的属性名转换后应该是:indexColor 。 示例:

<input type="button" value="按钮" index="10" data-index="10" data-index-color="red">
var oBtn=document.querySelector('input');

console.log(oBtn.dataset);                //DOMStringMap对象
console.log(oBtn.dataset.index);          //10
console.log(oBtn.dataset.indexColor);    //red
console.log(oBtn.index);                //undefined

console.log('name' in oBtn.dataset);    //falseoBtn.dataset.name='zpf';
console.log('name' in oBtn.dataset);    //trueoBtn.dataset.index=100;
console.log(oBtn.dataset.index);        //100oBtn.index=20;
console.log(oBtn.index);                //20

如果你想删掉一个 data-属性 ,可以这么做: delete el.dataset.index ; 或者 el.dataset.index = null ; 。

14. input disabled、readonly、和 hidden 的区别

  • disabled:无法使用无法点击的,可见,不会被提交
  • readonly:可以选中、不可修改,可见,可提交
  • hidden:不可见,可提交

15. WEB标准和W3C标准是什么

web标准:提倡结构、表现和行为相分离(HTML结构、CSS表现、JavaScript行为)
w3c标准:标签闭合,标签小写,嵌套正确,外部链接css和js

16. GET和POST的区别

  1. GET请求在浏览器回退和刷新时是无害的,而POST请求会告知用户数据会被重新提交;

  2. GET请求可以收藏为书签,POST请求不可以收藏为书签;

  3. GET请求可以被缓存,POST请求不可以被缓存,除非在响应头中包含合适的Cache-Control/Expires字段,但是不建议缓存POST请求,其不满足幂等性,每次调用都会对服务器资源造成影响;

  4. GET请求一般不具有请求体,因此只能进行url编码,而POST请求支持多种编码方式。

  5. GET请求的参数可以被保留在浏览器的历史中,POST请求不会被保留;

  6. GET请求因为是向URL添加数据,不同的浏览器厂商,代理服务器,web服务器都可能会有自己的长度限制,而POST请求无长度限制;

  7. GET请求只允许ASCII字符,POST请求无限制,支持二进制数据;

  8. GET请求的安全性较差,数据被暴露在浏览器的URL中,所以不能用来传递敏感信息,POST请求的安全性较好,数据不会暴露在URL中;

  9. GET请求具有幂等性(多次请求不会对资源造成影响),POST请求不幂等;

  10. GET请求一般不具有请求体,请求中一般不包含100-continue 协议,所以只会发一次请求,而POST请求在发送数据到服务端之前允许双方"握手",客户端先发送Expect:100-continue消息,询问服务端是否愿意接收数据,接收到服务端正确的100-continue应答后才会将请求体发送给服务端,服务端再响应200返回数据。

17. src 和 href 的区别

href标识超文本引用,用在link和a等元素上,href是引用和页面关联,是在当前元素和引用资源之间建立联系。

src表示引用资源,表示替换当前元素,用在img,script,iframe上,src是页面内容不可缺少的一部分。

18. 如何优化图片

19. 说说浏览器缓存机制

DNS 缓存

DNS查询过程如下:

  • 首先搜索浏览器自身的DNS缓存,如果存在,则域名解析到此完成。
  • 如果浏览器自身的缓存里面没有找到对应的条目,那么会尝试读取操作系统的hosts文件看是否存在对应的映射关系,如果存在,则域名解析到此完成。
  • 如果本地hosts文件不存在映射关系,则查找本地DNS服务器(ISP服务器,或者自己手动设置的DNS服务器),如果存在,域名到此解析完成。
  • 如果本地DNS服务器还没找到的话,它就会向根服务器发出请求,进行递归查询。

浏览器缓存分类

  • 强缓存Expires (http 1.0规范,主要用域浏览器兼容性),Cache-Control (http 1.1规范,优先级高于Expires)
  • 协商缓存Last-Modify/If-Modify-Since (服务器返回Last-Modify最后修改日期,客户端上传If-Modify-Since,用于服务器判断是否失效。主要根据时间进行判断)。ETag/If-None-Match (服务器返回ETag hash值,客户端上传If-None-Match,值是ETag的hash值,用于服务器判断是否失效,主要根据资源唯一标识hash值判断。优先级高于Last-Modify)

浏览器获取到资源后缓存的位置

  • memory cache (资源较小,容易变动的资源,退出浏览器会清除,优先级高于disk cache)
  • disk cache (资源较大,不容易变动的资源,退出浏览器不会清除)

浏览器资源访问流程

  1. 看看是否命中强缓存,如果命中,就直接使用缓存了。
  2. 如果没有命中强缓存,就发请求到服务器检查是否命中协商缓存。
  3. 如果命中协商缓存,服务器会返回 304 告诉浏览器使用本地缓存。
  4. 否则,返回 200 及最新的资源,浏览器将最新的资源缓存下来。

浏览器访问自身资源的流程

  1. 先在内存中查找,如果有,直接加载。
  2. 如果内存中不存在,则在硬盘中查找,如果有直接加载。
  3. 如果硬盘中也没有,那么就进行网络请求。
  4. 请求获取的资源缓存到硬盘和内存。

注意:如果什么缓存策略都没设置,浏览器会采用一个启发式的算法,通常会取响应头中的 Date 减去 Last-Modified 值的 10% 作为缓存时间。

用户行为对浏览器缓存的影响

  • 打开网页,地址栏输入地址: 查找 disk cache 中是否有匹配。如有则使用;如没有则发送网络请求。
  • 普通刷新 (F5):因为 TAB 并没有关闭,因此 memory cache 是可用的,会被优先使用(如果匹配的话)。其次才是 disk cache。
  • 强制刷新 (Ctrl + F5):浏览器不使用缓存,因此发送的请求头部均带有 Cache-control: no-cache(为了兼容,还带了 Pragma: no-cache),服务器直接返回 200 和最新内容。

参考链接
深入理解浏览器的缓存机制
实践这一次,彻底搞懂浏览器缓存机制

20. 从输入 URL 到页面加载全过程

  1. DNS缓存及IP的获取
  2. 浏览器缓存
  3. 计算机网络七层协议或五层协议
  4. TCP协议的三次握手及四次挥手
  5. 浏览器渲染及DOMContentLoaded、onload事件

以上为解答思路,具体可参照其余部分详细说明。

21. link preload和prefetch

<link rel="prefetch"> 的作用是告诉浏览器加载下一页面可能会用到的资源,注意,是下一页面,而不是当前页面。因此该方法的加载优先级非常低。

<link rel="subresource"> 的设计初衷是处理当前页面,但最后还是壮烈牺牲了。因为开发者无法控制资源的加载优先级,因此浏览器(其实也只有 Chrome 和基于 Chrome 的浏览器)在处理此类标签时,优先级很低,到底有多低呢?这么说吧,在大多数情况下,用了等于没用。

Preload是为处理当前页面所生,这点和 subresource 一样,但他们之间有着细微且意义重大的区别。Preload 有 as 属性

使用preload的好处:

  1. 将加载和执行分离开,不阻塞渲染和document的onload事件
  2. 提前加载指定资源,不再出现依赖的font字体隔了一段时间才刷出的情况

参考链接
资源预加载preload和资源预读取prefetch简明学习
关于Preload, 你应该知道些什么?

22. 浏览器组成

  1. 用户界面:
    用户界面主要包括:地址栏,后退/前进按钮,书签目录等;(除了从服务器请求到的网页窗口)
  2. 浏览器引擎:
    用来查询及操作渲染引擎的接口;
  3. 渲染引擎:
    用来显示请求的html内容;(包括样式,图片,js)
  4. 网络:
    主要是来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作;
  5. UI后端:
    用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台的通用接口,底层使用操作系统的用户接口。
  6. JS解释器 :
    用来解释执行JS代码;
  7. 数据存储:
    属于持久层,浏览器需要在硬盘中保存类似cookie的各种数据,HTML5定义了web database技术,这是一种轻量级完整的客户端存储技术;

参考链接:
浏览器有哪几部分组成及各组成部分的作用

H5新增废弃了哪些元素标签

废弃标签:

  1. 能用CSS代替的元素:basefont、big、center、font、s、strike、tt、u
  2. frame框架:frameset、frame、noframes。
  3. 只有部分浏览器支持的元素:applet、bgsound、blink、marquee
  4. 其他元素:rb、acronym、dir、isindex、listing、xmp、nextid、plaintex

新增标签:

  1. 结构标签:section、article、aside、header、hgroup、footer、nav、figure
  2. 表单标签:email、url、number、range、Date Pickers、color、tel
  3. 媒体标签:video、audio、embed
  4. 功能标签:mark、progress、time、ruby、rt、wbr、canvas、details、datalist、keygen

参考链接:
HTML5新增和废弃的标签

行内元素有哪些,块级元素有哪些,空元素有哪些

行内元素有:

  • a( 锚点)
  • b(粗体)
  • span(常用内联容器,定义文本内区块)
  • img(图片)
  • input(输入框)、select(项目选择)、button(按钮)、textarea(文本域)、label(表格标签)
  • strong(粗体强调)、i(斜体)、em(强调)、mark(高亮显示文本)、cite(引用)、dfn(一个定义项目)
  • code(计算机代码)

块级元素有:

  • div
  • ul(无序列表)、li
  • ol(有序列表)
  • dl(定义列表)、dt、dd
  • form(表单)
  • h1 (一级标题))、h2、h3、h4、h5、h6
  • p(段落)
  • pre(预格式化)
  • blockquote(引用)

常见的空元素:

  • br
  • hr
  • img
  • input
  • link
  • meta

鲜为人知的空元素:

  • area
  • base
  • col
  • command
  • embed
  • keygen
  • param
  • source
  • track
  • wbr

canvas和svg的区别

Canvas

  • 依赖分辨率
  • 不支持事件处理器
  • 弱的文本渲染能力
  • 能够以 .png 或 .jpg 格式保存结果图像
  • 最适合图像密集型的游戏,其中的许多对象会被频繁重绘

SVG

  • 不依赖分辨率
  • 支持事件处理器
  • 最适合带有大型渲染区域的应用程序(比如谷歌地图)复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快)
  • 不适合游戏应用
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
禁止转载,如需转载请通过简信或评论联系作者。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容