分享

Chrome(谷歌)浏览器调试教程珍藏版

 天使之翼 ` 2019-06-25

前言

 鸣谢殷老师,非常优秀的学习资料,分享给大家,希望对大家有帮助!

                                                        JavaEE助教  殷世腾

引言

在web开发过程中,我们在写JavaScript脚本时难免会遇到各种bug,这时,我们就需要去调试我们的JavaScript脚本,然后去修改代码。最简单的调试方法就是使用alert方法,将可信息通过alert方法的弹窗显示出来。但是,alert方法有几个弊端:

1)alert方法在弹出窗口时会中断程序;
2)在循环中使用alert()方法时,如果不点击alert弹窗的确定按钮,下一个alert就不会出现;
3)alert方法在显示对象时永远只显示[Object],无法看到对象中的具体细节;
正是由于alert方法存在上述缺点导致了alert方法只适合一些小程序。如果想要查看JavaScript脚本的执行过程,HTTP请求信息,执行过程中的数据信息则需要学会使用浏览器的开发者工具进行调试。

学习目标:
1.Chrome浏览器简介及下载与安装(了解);
2.浏览器加载Html页面的过程(了解);
3.Chrome浏览器开发者工具面板的介绍(熟悉);
4.使用Chrome开发者工具调试JavaScript脚本(掌握);
5.Chrome浏览器的其他设置(了解);

1.浏览器简介

这里写图片描述

浏览器界面:

浏览器的用户界面有很多彼此相同的元素,其中包括:
用来输入 URI 的地址栏
前进和后退按钮
书签设置选项
用于刷新和停止加载当前文档的刷新和停止按钮
用于返回主页的主页按钮

浏览器的主要功能:

  浏览器的主要功能就是向服务器发出请求,在浏览器窗口中展示您选择的网络资源。这里所说的资源一般是指 HTML 文档,也可以是 PDF、图片或其他的类型。资源的位置由用户使用 URI(统一资源标示符)指定。
  浏览器解释并显示 HTML 文件的方式是在 HTML 和 CSS 规范中指定的。这些规范由网络标准化组织 W3C(万维网联盟)进行维护。
多年以来,各浏览器都没有完全遵从这些规范,同时还在开发自己独有的扩展程序,这给网络开发人员带来了严重的兼容性问题。如今,大多数的浏览器都是或多或少地遵从规范。 
简而言之,就是一个获取网页,并将它显示给用户的工具。

浏览器的高层结构

浏览器的主要组件为 (1.1):
用户界面 - 包括地址栏、前进/后退按钮、书签菜单等。除了浏览器主窗口显示的您请求的页面外,其他显示的各个部分都属于用户界面。
浏览器引擎 - 在用户界面和呈现引擎之间传送指令。
呈现引擎 - 负责显示请求的内容。如果请求的内容是 HTML,它就负责解析 HTML 和 CSS 内容,并将解析后的内容显示在屏幕上。
网络 - 用于网络调用,比如 HTTP 请求。其接口与平台无关,并为所有平台提供底层实现。
用户界面后端 - 用于绘制基本的窗口小部件,比如组合框和窗口。其公开了与平台无关的通用接口,而在底层使用操作系统的用户界面方法。
JavaScript 解释器-用于解析和执行 JavaScript 代码。
数据存储-这是持久层。浏览器需要在硬盘上保存各种数据,例如 Cookie。新的 HTML 规范 (HTML5) 定义了“网络数据库”,这是一个完整(但是轻便)的浏览器内数据库。

我们这里谈到的浏览器:

这里写图片描述

目前使用的主流浏览器有五个:Internet Explorer、Firefox、Safari、Chrome 浏览器和 Opera。本文中以开放源代码浏览器为例,即 Firefox、Chrome 浏览器和 Safari(部分开源)。根据 StatCounter 浏览器统计数据,目前(2011 年 8 月)Firefox、Safari 和 Chrome 浏览器的总市场占有率将近 60%。由此可见,如今开放源代码浏览器在浏览器市场中占据了非常坚实的部分。

1.1下载与安装
下载地址:http://www.google.cn/intl/zh-CN/chrome/browser/desktop/index.html

这里写图片描述

安装:傻瓜式的安装,一路点击下一步。

2.浏览器加载Html页面的过程
2.1 从输入URL到页面加载完成都发生了什么?

这里写图片描述

1.处理URL:输入 URL 后的「回车」,这时浏览器会对 URL 进行检查,首先判断协议,如果是 http 就按照 Web 来处理,另外还会对这个 URL 进行安全检查,然后直接调用浏览器内核中的对应方法,比如 WebView 中的 loadUrl 方法。

2.发送HTTP请求:因为网络的底层实现是和内核相关的,所以这一部分需要针对不同平台进行处理,从应用层角度看主要做两件事情:通过 DNS 查询 IP、通过 Socket 发送数据,接下来就分别介绍这两方面的内容。

2.1 DNS查询:Chrome浏览器在启动的时候首先会去加载你本地的host文件,如果URL中的域名在host文件中设置的有对应的IP地址,就会直接将这个域名指向这个地址。如果host中没有URL中输入的域名(www.baidu.com)对应的IP地址,浏览器就会去访问DNS服务器,向DNS服务器询问这个域名(www.baidu.com)对应的IP地址。

2.2 通过Socket发送数据:有了 IP 地址,就可以通过 Socket API 来发送数据了,这时可以选择 TCP/IP 或 UDP 协议,HTTP 常用的是 TCP/IP 协议。Chrome此时就会使用TCP/IP传输协议,将URL中的信息通过HTTP协议发送到百度的服务器。

3.浏览器接受远程服务器响应的数据:远程服务器(百度的服务器)一般会返回给浏览器一个HTML(字节码数据)。浏览器接受到数据之后就对这些字节码数据以指定的编码格式进行解码。浏览器获取编码格式的途径:

1)用户设置,在浏览器中可以指定页面编码
2)HTTP 协议中
3)HTML页面中 的 charset 属性值

4.浏览器对HTML页面进行渲染和布局:
1).浏览器开始载入html代码,发现<head>标签内有一个<link>标签引用外部CSS文件;
2).浏览器又发出CSS文件的请求,服务器返回这个CSS文件;
3).浏览器继续载入html中<body>部分的代码,并且CSS文件已经拿到手了,可以开始渲染页面了;
4).浏览器在代码中发现一个<img>标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是继续渲染后面的代码;
服务器返回图片文件,由于图片占用了一定面积,影响了后面段落的排布,因此浏览器需要回过头来重新渲染这部分代码;
5).浏览器发现了一个包含一行Javascript代码的<script>标签,赶快运行它;
6).Javascript脚本执行了这条语句,它命令浏览器隐藏掉代码中的某个<div> (style.display=”none”)。杯具啊,突然就少了这么一个元素,浏览器不得不重新渲染这部分代码;
7).终于等到了</html>的到来,浏览器泪流满面……
8).等等,还没完,用户点了一下界面中的“换肤”按钮,Javascript让浏览器换了一下<link>标签的CSS路径;
9).浏览器召集了在座的各位<div><span><ul><li>们,“大伙儿收拾收拾行李,咱得重新来过……”,浏览器向服务器请求了新的CSS文件,重新渲染页面。
注:win10打开host文件的方法:在运行(win+R)中输入:C:\Windows\System32\drivers\etc即可

2.2 JavaScript引擎

2.2.1 JavaScript引擎是什么?
“JavaScript引擎”通常被称作一种 虚拟机。“虚拟机”是指软件驱动的给定的计算机系统的模拟器。有很多类型的虚拟机,它们根据自己在多大程度上精确地模拟或代替真实的物理机器来分类。

2.2.2 JavaScript引擎是干什么的?
JavaScript的基本工作就是将开发者写的JavaScript代码转换成能被浏览器理解甚至能在应用程序上运用的最优化的快捷代码。比方说,当你写了 var a = 1 + 1; 这样一段代码,JavaScript引擎做的事情就是看懂(解析)你这段代码,并且将a的值变为2。

2.2.3 主要的JavaScript引擎有哪些?
WebKit的JavaScriptCore 和 Google 的 V8 引擎。

2.2.4 JavaScriptCore和V8引擎解析源代码的过程
JavaScriptCore 执行 一系列步骤 来解释和优化脚本:
1)首先它进行词法分析,就是将源代码分解成一系列具有明确含义的符号或字符串。
2) 然后用语法分析器分析这些符号,将其构建成语法树。
3)接着四个 JIT(Just-In-Time)进程开始参与进来,分析和执行解析器所生成的字节码。
简单来说,JavaScript 引擎会加载你的源代码,把它分解成字符串(又叫做分词),再 把这些字符串转换 成编译器可以理解的字节码,然后执行这些字节码。

Google 的 V8 引擎 是用 C++ 编写的,它也能够编译并执行 JavaScript 源代码、处理内存分配和垃圾回收。它被设计成由两个编译器组成,可以把源码直接编译成机器码:

1) Full-codegen:输出未优化代码的快速编译器
2) Crankshaft: 输出执行效率高、优化过的代码的慢速编译器
如果 Crankshaft 确定需要优化的代码是由 Full-codegen 生成的未优化代码,它就会取代 Full-codegen,这个过程叫做“crankshafting”。
一旦编译过程中产生了机器代码,引擎就会向浏览器暴露所有的数据类型、操作符、对象、在 ECMA 标准中指定的函数、或任何运行时需要使用的东西,NativeScript 就是如此。

3.Chrome浏览器的开发者工具面板介绍

这里写图片描述

3.1 Chrome浏览器开发者工具的打开方式:
1)功能键F12或者Ctrl+Shift+j或者Ctrl+Shift+j打开;
2)打开浏览器右上角用户设置下拉菜单,选择更多工具,再选择开发者工具即可打开开发者工具。

这里写图片描述

3.2 开发者工具的工具栏中常用面板介绍

这里写图片描述

Elements:查找网页源代码HTML中的任一元素,手动修改任一元素的属性和样式且能实时在浏览器里面得到反馈。
Console:记录开发者开发过程中的日志信息,且可以作为与JS进行交互的命令行Shell。

Sources: Sources功能面板是资源面板,他主要分为四个部分,四个部分并不是独立的,他们互相关联,互动共同实现一个重要的功能:监控js在执行期的活动。简单来说就是断点啦。

Network:从发起网页页面请求Request后分析HTTP请求后得到的各个请求资源信息(包括状态、资源类型、大小、所用时间等),可以根据这个进行网络性能优化。
Timeline:记录并分析在网站的生命周期内所发生的各类事件,以此可以提高网页的运行时间的性能。
Profiles:如果你需要Timeline所能提供的更多信息时,可以尝试一下Profiles,比如记录JS CPU执行时间细节、显示JS对象和相关的DOM节点的内存消耗、记录内存的分配细节。
Application:记录网站加载的所有资源信息,包括存储数据(Local Storage、Session Storage、IndexedDB、Web SQL、Cookies)、缓存数据、字体、图片、脚本、样式表等。
Security:判断当前网页是否安全。
Audits:对当前网页进行网络利用情况、网页性能方面的诊断,并给出一些优化建议。比如列出所有没有用到的CSS文件等。

3.2.1 元素(Element)面板
Element面板打开方式:
1)打开开发者工具后选择开发者工具面板中的Element页签;
这里写图片描述

2)打开浏览器之后,鼠标右键检查 (火狐浏览器是” 审查元素”)
这里写图片描述

Element面板的常用功能:
1)实时编辑DOM节点
在Element面板的DOM树视图中.呈现出了当前页面中的所有的DOM节点.鼠标双击任何DOM节点都可以修改其中的属性值,修改完成之后按回车键浏览器会立即显示出修改后的效果.
注意:这种及时的修改只是临时的修改,只能做调试用,实际应用中往往是调试结束后再将正确的属性值在本地代码中修改.

这里写图片描述

2)实时编辑CSS样式
在Element面板中也可以对当前页面的DOM元素的样式进行实时的修改,修改后元素的样式立即生效.
实时修改某一DOM元素的样式的操作步骤:
首先选中这个DOM元素.如果没有打开开发者工具,可以在要修改的DOM元素上右键–>审查元素,然后选择控制面板右侧的Style即可看到当前DOM元素的所有CSS样式,双击其中的CSS属性值就可以修改,修改后马上生效.如果已经打开了开发者工具,可以通过先点击开发者工具面板最左侧的放大镜,然后再去点击页面上要修改的DOM元素选中这个要调试的DOM元素.此时控制面板右侧的Style中就呈现出了当前选中的DOM元素的CSS属性双击属性值即可修改.
注意:这种及时的修改只是临时的修改,只能做调试用,实际应用中往往是调试结束后再将正确的属性值在本地代码中修改.

这里写图片描述

3)打开盒子模型,调试边框参数
点击右侧的Computed页签可以看到当前选中的元素的盒子模型参数,所有的值都是可以修改的.点击不同的位置(top,bottom,left,right)就可以修改元素的padding,border,margin属性值.也可以通过修改盒子模型中间的数据改变元素的width和height.修改的时候浏览器中的当前元素会响应地变化,同时在左侧Element面板中会自动添加上响应的Stylt属性值.当页面上显示的样式符合要求之后,即可停止修改,然后将Element中生成的属性值复制到代码中,样式即可永久修改.

这里写图片描述

3.2.2 控制台(Console) 面板
1)查看脚本运行过程中的异常信息;
由于JavaScript属于弱语言类型,语法要求不严谨.并且JavaScript是解释型语言,在代码中输入中文的标点等错误也不会有提示,只有运行结束后才会抛出异常信息到控制台.

这里写图片描述
如果想查看具体的异常信息,直接点击右边的异常信息控制台将会把我们带到程序中错误出现的具体位置:

这里写图片描述

2)打印日志信息;

上边说到了简单的调试可以使用alert方法将想要看到的信息显示在弹窗中。但是alert存在弊端:阻断程序运行,不能显示对象的细节信息,弹出多个信息时必须点击确定才能看到下一个弹窗的信息。这些问题使用console提供的打印日志的方法可以完美解决。
Console常用的打印日志的方法有:
A)console.log(“info”)显示一般的基本日志信息,当要显示的基本日志信息太多时,可以使用console.grop()方法将日志分组;
B)Console.warn(“info”)显示带有黄色小图标的警告信息;
C)Console.error(“info”)显示带有红色小图标的错误信息;
Console打印日志的使用场景:
A)在代码中使用console.log()打印日志信息:

这里写图片描述
B)直接在控制台上使用console.log()打印信息:

这里写图片描述

C)清除控制台中信息的方法:

直接在控制台上输出console.clear()方法人后回车即可清除控制台上的信息。还有一种方法是直接点击控制台左上方的清除日志的按钮清除日志信息。

这里写图片描述

3)运行JavaScript脚本

控制台还有一个神奇的功能就是可以运行你输入的JavaScript脚本,这一点非常实用。
实用场景一:快速验证JavaScript中的方法。
将一个小数按照输出,要求:只保留两位小数。通过查JavaScript的API得知Number对象有一个toFixed方法可以指定小数位的长度,但是又没有例子,最快的尝试方法就是在控制台上验证:
console.log(new Number(“3.1415926”).toFixed(2));

这里写图片描述

实用场景二:控制台中输入JavaScript方法时有提示。

通过document获取指定id的节点的方法是document.getElementById(“id”)但是因为MyEclipse,Eclipse中在写JavaScript时可能没提示,自己写太痛苦而且还容易写错。这时,就可以在控制台上通过方法提示来补全这个方法。

这里写图片描述
如上图:我们不需要完整输入方法名,根据提示使用键盘的上,下键选择需要的方法然后回车即可。

D)Console面板中的全局搜索(快捷键Ctrl+Shift+F)
打开全局搜索,输入关键字,能够搜索到包含这个关键字的所有的文件。
应用场景:刚到一个公司,对公司的业务不熟。登录页面有几千行代码,我只想找到登录的那个方法。这时,输入登录方法名就能搜索到登录登录方法所在的页面。点击进去就能够定位到这个方法了。

这里写图片描述

3.2.3 资源(Source) 面板
Source资源面板中显示加载当前页面需要的所有资源。

这里写图片描述

在Source面板中可以找到当前浏览器加载的页面,然后对其中的JavaScript脚本进行断点调试。Chrome开发者工具使用中会具体说明。
3.2.4 网络(NetWork) 面板
NetWork面板可以记录页面上的网络请求的详细信息,从发起网页请求Request后分析HTTP请求后得到的各个请求资源信息(包括状态,资源信息,大小,所用时间,Request和Response等),可以根据这个进行网络性能优化。

这里写图片描述

1.Controls 控制Network的外观和功能。
2.Filters 控制Requests Table具体显示哪些内容。
3.Overview 显示获取到资源的时间轴信息。
4.Requests Table 按资源获取的前后顺序显示所有获取到的资源信息,点击资源名可以查看该资源的详细信息。
5.Summary 显示总的请求数、数据传输量、加载时间信息。

NetWork面板的Requests Table 包含着HTTP请求和响应的具体信息,是比较常用的一块
Name 资源名称,点击名称可以查看资源的详情情况,包括Headers、Preview、Response、Cookies、Timing。
Status HTTP状态码。
Type 请求的资源MIME类型。
Initiator 标记请求是由哪个对象或进程发起的(请求源)。
Parser: 请求由Chrome的HTML解析器时发起的。
Redirect:请求是由HTTP页面重定向发起的。
Script:请求是由Script脚本发起的。
Other:请求是由其他进程发起的,比如用户点击一个链接跳转到另一个页面或者在地址栏输入URL地址。
Size 从服务器下载的文件和请求的资源大小。如果是从缓存中取得的资源则该列会显示(from cache)
Time 请求或下载的时间,从发起Request到获取到Response所用的总时间。
Timeline 显示所有网络请求的可视化瀑布流(时间状态轴),点击时间轴,可以查看该请求的详细信息,点击列头则可以根据指定的字段可以排序。

查看具体资源的详情
通过点击某个资源的Name可以查看该资源的详细信息,根据选择的资源类型显示的信息也不太一样,可能包括如下Tab信息:
Headers 该资源的HTTP头信息。
Preview 根据你所选择的资源类型(JSON、图片、文本)显示相应的预览。
Response 显示HTTP的Response信息。
Cookies 显示资源HTTP的Request和Response过程中的Cookies信息。
Timing 显示资源在整个请求生命周期过程中各部分花费的时间。
针对上面4个Tab进行详细讲解一下各个功能:
① 查看资源HTTP头信息
在Headers标签里面可以看到HTTP Request URL、HTTP Method、Status Code、Remote Address等基本信息和详细的Response Headers
、Request Headers以及Query String Parameters或者Form Data等信息。

这里写图片描述

预览响应数据

这里写图片描述

③ 查看资源HTTP的Response信息
在Response标签里面可根据选择的资源类型(JSON、图片、文本、JS、CSS)显示相应资源的Response响应内容。下图显示的是当选择的资源是CSS格式时的响应内容。

这里写图片描述

④ 查看资源Cookies信息
如果选择的资源在Request和Response过程中存在Cookies信息,则Cookies标签会自动显示出来,在里面可以查看所有的Cookies信息。

这里写图片描述

4.Chrome开发者工具之断点调试

4.1 JavaScript脚本断点调试

第一步:打开开发者工具,按F12或者在浏览器页面上右键选择检查。

这里写图片描述

第二步:在Source面板中找到需要调试的文件。

这里写图片描述

第三步:设置断点。

这里写图片描述
第四步:触发调试部分程序的运行,开始调试。

这里写图片描述

调试过程中常用的按钮及快捷键:

跳到下一个断点:点击Sources面板右侧的“三角按钮”

这里写图片描述
快捷键:F8
Ctrl+\
跳到下一步(逐步跨方法):点击Sources面板右侧的第二个按钮

这里写图片描述
快捷键:F10
Ctrl+’
跳进断点处的方法中:点击Sources面板右侧第三个按钮

这里写图片描述
快捷键:F11
Ctrl+;
跳出正在执行的方法:点击Sources面板右侧第四个按钮

这里写图片描述
快捷键:Shift+F11
Ctrl+Shift+;

禁用断点:点击Sources面板右侧的第五个按钮

这里写图片描述

暂停在捕获到的异常处:点击Sources面板右侧的第六个按钮,然后勾选Pause On Caught Exception

这里写图片描述

暂停在未捕获的异常处:点击Sources右侧的第六个按钮,不勾选Pause On Caught Exception.

这里写图片描述
Sources面板调试过程中快捷键预览:
这里写图片描述

查看断点处,获取的数据的值:
将鼠标光标停留在变量上面即可,也可以将变量赋值到Console的控制台上打印出来。

这里写图片描述

这里写图片描述

清除断点:
在Source面板最右侧面板中,找到Breakpoints打开,可以看到你打的断点。在断点列表出右键选择Remove all breakpoints可以一次性删除所有断点。

这里写图片描述
4.2 XHR断点调试

右侧调试区有一个 XHR Breakpoints,点击+ 并输入 URL 包含的字符串即可监听该 URL 的 Ajax 请求,输入内容就相当于 URL 的过滤器。如果什么都不填,那么就监听所有 XHR 请求。一旦 XHR 调用触发时就会在 request.send() 的地方中断。

4.3 事件监听断点

事件监听是对我们选定的是事件类型进行监听,当这个事件触发的时候,程序就会在这个事件处停止。有助于我们快速找到某一个元素上绑定的事件。
应用场景:我们刚接手一个项目时,对业务不熟。想找到提交登录事件对应的方法,但是发现页面上登录按钮绑定事件写的不是很明确,而且处理登录业务的JavaScript脚本文件有几百行,想找到这个按钮很不容易。此时,我们就可以选定鼠标的点击事件进行监听,当我们点击登录按钮的时候控制台Sources面板会自动将我们带到登录方法处。
事件监听断点使用步骤(以查找天猫首页登录方法为例):

1.首先打开京东登录页面找到登录按钮;
这里写图片描述

2.在登录按钮上右键属性==》检查 打开开发者工具,然后打开Sources面板
这里写图片描述

这里写图片描述

3.打开Sources面板右侧的Event Listener Breakpoints 找到Mouse及鼠标事件下边的click然后勾选上。

这里写图片描述

  1. 点击登录按钮,触发鼠标的点击事件,发现程序中断在JavaScript文件中,点击面板下方的 “{}” 将代码格式化一下,此时就找到了登录按钮触发的点击事件了。

这里写图片描述

此时就可以一步一步的像下跟,知道跟到天猫的登录方法了。

5 其他设置

5.1 设置开发者工具的位置:

Chrome刚安装好时,打开开发者工具,开发者工具默认在浏览器的左半边。

这里写图片描述

可以通过开发者工具面板右上角的设置开发者工具在浏览器中出现的位置。

这里写图片描述

视图1:开发者工具以一个独立的窗口存在;视图2:在浏览器下方显示;视图3:在浏览器右半边显示。

5.2 清除浏览器缓存的方法:

浏览器缓存(Browser Caching)是为了节约网络的资源加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样就可以加速页面的阅览。但是,对开发人员来说,我们修改了JavaScript脚本之后需要立即看到修改的效果,所以需要清除缓存,清除缓存常用的方法有:

1.Ctrl + F5

F5通常只是刷新本地缓存;Ctrl+F5可以把INTERNET临时文件夹的文件删除再重新从服务器下载,也就是彻底刷新页面了。

2.开发者工具打开之后,快速清除缓存的方法:

开发者工具打开之后,浏览器刷新图标上右键会出现清空缓存并硬性重新加载。这一方法能够在开发者工具打开时快速清理缓存。

这里写图片描述
3.Ctrl + Shift + Del 快捷键清除缓存。
选中地址栏中的URL

这里写图片描述
按快捷键:Ctrl + Shit + Del 会弹出一个清除浏览数据的弹窗,选择要清理的数据项之后,点击清除浏览数据即可。

这里写图片描述

5.3 禁用页面的JavaScript脚本;
应用场景:在开发互联网电商项目时,需要一些商品图片,于是就去京东找到一个商品打开商品图片之后,想复制或者将这个图片另存为,此时,发现右键后什么都没有。
这里写图片描述

原因是,京东在图片上通过JavaScript脚本禁用了鼠标右键点击事件。此时,我们可以通过禁用当前页面的JavaScript事件,通过鼠标右键保存图片。

这里写图片描述

禁用网页JavaScript事件的方法:

1)开发者工具==》Settings

这里写图片描述

2)勾选Debugger下的Disable JavaScript 复选框。

这里写图片描述

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多