前端发展史
1990年,那是一个冬天,有一位老人在欧洲核子研究中心织了一张网,神话般的诞生了万维网。
很久很久以前(1980 年),在欧洲核子研究中心工作的一位英国物理学家「蒂姆·伯纳斯-李」为了让研究人员能够分享和更新他们的研究结果,他与「罗勃·卡力奥」一起建立了一个叫做 ENQUIRE [ɪn’kwaɪə(r)] 的原型系统,这就是万维网的前身。后来他想将这种方式嫁接到因特网上,1990 年圣诞节那天编写出了全球首个网页浏览器 WorldWideWeb(同时也是网页编辑器,后来为了避免与万维网混淆而改名为 Nexus [‘neksəs])和网页服务器。这套服务器在欧洲核子研究中心于 1991 年 8 月 6 日上线,这就是全球第一个万维网网站。
HTML(超文本标记语言)、HTTP(超文本传输协议)以及 URI(统一资源标志符,也就是在浏览器输入的地址规则)都是这位大佬发明的。
WorldWideWeb 的模拟界面如下:
这个浏览器有以下功能:
- 显示文本、图片
- 打开超链接
- 编辑所示内容
点击此链接可以查看此网页版模拟界面:https://worldwideweb.cern.ch/browser/
这个界面也很经典,截止目前(2019 年 11 月 20 日),WPS、Microsoft Office 的界面都和它极为相似
这个时候,万维网这玩意儿在科研领域迅速流传开了。大家都知道,科研领域流行了和普通用户间流行了差别还是很大的,在普通用户中流行不起来的原因是大家没有这种可以读取 HTML 文件的程序,用文本读取软件读取出来的话就和现在浏览器右键查看网页源码一个样。
既然没有这种软件,那下一步就应该有人要做这样的一个软件了。
两年后(1993 年 3 月),伊利诺斯大学的「马克·安德列森(MarcAndreessen)」领着一群学生写出了 Mosaic [məʊ’zeɪɪk],这是第一个面向普通用户使用的读取 HTML 文件的程序,从此万维网这玩意儿才走进了普通人的世界。又过了一年(1994 年),上面开发浏览器的这波人和 SGI 公司的「詹姆斯·克拉克(JamesClark)」合作成立了网景公司,开发了 Netscape Navigator [‘nævɪ.ɡeɪtə(r)] 浏览器。后来 JavaScript 就是因为它进入了大家的视野。
网景的浏览器没用 Mosaic 的代码,但是网景的一个对头 —— 微软开发的 IE 浏览器却用了 Mosaic 的源码。这中间关系有点复杂就不细说了,想了解的小伙伴可以查看词条 Internet Explorer 、 Mosaic 浏览器和 Netscape 浏览器。
网景浏览器现在虽然消失了,但是其另一个分支 —— Mozilla Firefox 还活着,他们之间的关系可查看词条:Mosaic 浏览器 和 Mozilla基金会。
1994 年,网景预见到网络需要变得更动态,以及 HTML 需要一种「胶水语言」让网页设计师和兼职程序员可以很容易地使用它来组装图片和插件之类的组件,且代码可以直接编写在网页标记中。
1995年,网景招募了布兰登·艾克,目标是把 Scheme 语言嵌入到 Netscape Navigator 浏览器当中。但更早之前,网景已经跟 Sun 合作在 Netscape Navigator 中支持 Java,这时网景内部产生激烈的争论。后来网景决定发明一种与 Java 搭配使用的辅助脚本语言并且语法上有些类似。最初命名为 Mocha [ˈmɒkə],后来改名为 LiveScript,最后网景公司与 Sun 组成的开发联盟为了让这门语言搭上 Java 这个编程语言「热词」,将其临时改名为 JavaScript(一个临时的名字成了永久的名称)。
JavaScript 在发明初期是针对非程序员设计的脚本语言,其标准版本是 ECMAScript,由网景通讯公司(Netscape)提交给欧洲标准协会制订。尽管它的名字和 Java 类似,但是它是由网景公司开发的而不是由太阳计算机系统公司(Sun Microsystems)开发的,除了两者的语法都是从 C 语言发展而来这一点外,它们之间几乎没有什么关系。之所以叫 JavaScript,只是当时网景公司希望能借助 Java 的名气推广它。时至今日 JavaScript 不仅可以用于网页开发,还强大到可以进行 PC 软件开发、手机 APP 开发、服务后台开发。
现在前端又出现了微软开发的 TypeScript,这玩意儿官方定义是 JavaScript 的超集。什么意思呢?就是说 JavaScript 原有的语言特性太少了,就搞出来一个语言特性更丰富的语言,然后还支持 JavaScript 的所有语法。但是 TypeScript 不能直接在浏览器运行,需要编译成 JavaScript 才能在浏览器运行。绕了这么一圈,那 TypeScript 是不是就感觉很鸡肋呢?其实不是这样的,TypeScript 解决了前端工程化问题和编写时的语法检查能力。其他的我们在后文「前端生态」来综合说明。
前端生态
开发语言
HTML:https://developer.mozilla.org/zh-CN/docs/Web/HTML
超文本标记语言,一种特定标签组合的 XML。
CSS:https://developer.mozilla.org/zh-CN/docs/Web/CSS
层叠样式表,描述 HTML 或 XML 文件在屏幕上绘制成什么样子。
JavaScript:https://www.javascript.com/
浏览器脚本语言(动态解释语言),通过操作 HTML 实现动态交互,学习和查阅资料:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
TypeScript:https://www.typescriptlang.org/
TypeScript 是静态编译语言,JavaScript 的超集,需编译成 JavaScript 才能在浏览器运行。
解决 JavaScript 工程化问题和 JavaScript 编写时容易导致的语法错误,比 JavaScript 多了如下语法特性:
- 类型批注和编译时类型检查
- 类
- 接口
- 模块
- lambda 函数
语法简介
HTML
html 是一种具有特定元素的 xml,这些特定的元素称为 html 标签,如下所示:
1 |
|
我们来和 mybatis 的 mapper.xml 文件对比一下:
1 |
|
html 的标签比 xml 文件要求宽松一些,xml 中的标签必须有结束标签,html 部分标签是可以没有结束标签的,如上方的 <img>
标签就没有结束标签 </img>
末尾也不是 />
,其它类似还包括 <br>
、<hr>
、<meta>
、<link>
等。
html 标签也有属性,包括标准的和自定义属性都可以。
现在我们来一个个对照解释 html 中的内容:
<!DOCTYPE html>
— 文档类型。这个的作用和 xml 中的一致,用于申明文件的根元素是什么以及文档中允许出现什么样的标签。html 中一般可以省略不写,在 mybatis 中是必须的,其余 xml 中是否要求必须写解析器有关。<html></html>
— 根元素。页面中所有元素一般要求在这个标签里,但是实际上在它外面或没有它也不会有多大问题。和 mybatis 中的<mapper>
元素作用一致。<head></head>
—<head>
元素。包含标题、搜索关键字(keywords)、页面描述、CSS 样式表和字符编码声明等。<meta charset="utf-8">
— 指定文档编码,这里使用 UTF-8 字符编码,类似 xml 中<?xml version="1.0" encoding="UTF-8"?>
,<meta>
标签还可以有其它的很多作用,还包括添加页面描述、搜索关键字等。<title></title>
—<title>
元素。设置页面的标题,显示在浏览器标签页上,将网页加入书签的时候显示的描述文字也是这个内容。<body></body>
—<body>
元素。这个元素包含期望让用户在访问页面时看到的内容,可以是文本、图像、视频、游戏、可播放的音轨或其他内容。<img>
— 图片元素,用于在浏览器中显示图片。
JavaScript
JavaScript 和 TypeScript 基本语法是一致的,因为 TypeScript 全兼容 JavaScript。
JavaScript 与 Java 语言相比,缺少以下这些语言特性:
- 类
- 继承
- 方法重载
- 泛型
- 注解
这些语法特性又在 TypeScript 上实现了,从使用角度来说 TypeScript 更像 Java,但是即使是 TypeScript 也不能重载。
函数
JavaScript 有一个 Java 没有的特性:可以在任何地方定义方法,包括将方法赋值给变量直接执行。比如:
正常情况下的函数定义
1 | function fn() { |
定义了一个 fn 变量,用于指向一个匿名函数
1 | var fn = function() { |
定义了一个 Map,每一个 key 对应一个匿名函数
1 | var fnMap = { |
在函数中定义函数,并返回这个函数
1 | function fnBack() { |
变量
通过以上例子可以看到,定义变量的时候在变量前使用 var
关键字。JavaScript 中只能用 var
来定义关键字,ES6 增加了 const
和 let
关键字。
ES5 于 2009 年完成标准化
ES6 于 2015 年 6 月发布第一个版本
const
用来定义不可修改的变量,等同于 Java 中变量前加 final
关键字。
let
的目的是替换掉 var
关键字。
为什么使用 let
关键字,看下面两个函数即可明白:
1 | function varTest() { |
多的就不说了,大家可以在任意的地方学习这些基础内容,下面我来给大家介绍一些 JavaScript 特殊的用法,这些用法经常用到,但是很少有地方针对性的介绍他们。
使用 ||
设置默认值
这个例子是使用百度统计时,要求加入你网站中的代码。
1 | var _hmt = _hmt || []; |
我们来看这段代码第一行 var _hmt = _hmt || [];
。
表达的意思是:
- 定义
_hmt
变量 - 判断
_hmt
变量的值是否为真,若为真则将_hmt
的值赋值给新定义的_hmt
变量;若为假,赋值一个空数组给_hmt
变量
翻译成比较好认的写法:
1 | var _hmt; |
这里隐藏两个 JavaScript 的语法规则:
用
var
声明的变量,如果你重新声明一个 JavaScript 变量,它将不会丢失其值。也就是说无论写多少次var _hmt;
其效果都一样,而且后定义的值不会覆盖前面赋予的值。任何一个值,只要它不是
undefined
、null
、0
、NaN
或空字符串(""
),那么无论是任何对象,即使是值为假的Boolean对象,在条件语句中都为真。例如:1
2
3
4var b = new Boolean(false);
if (b) {} // 表达式的值为true
b = false;
if (b) {} // 表达式的值为false
立即执行函数
我们继续看百度统计脚本,删掉第一行和函数里的代码如下:
1 | (function() { |
这种写法在大部分的 JS 框架中都能看到,这一段代码表示,定义一个匿名的函数,函数定义完毕后立刻执行这个函数,等同于下面的写法:
1 | var fn = function() {} |
与之类似有如下写法:
1 | (function(){})() |
这样的写法有两个好处:
- 不污染命名空间。JS 中的函数不能重载,如果框架用的名称和业务代码里的冲突了,那么就会导致功能不一致。
- 异步请求。还是用百度统计的代码来说,其实那一串代码最终就是在网页插入里一个
scprit
标签,然后通过这个标签加载一段 JS 代码,通过这种方式写入DOM的 script 标签,能避免对浏览器渲染DOM、加载后续script的阻塞,但是依然会阻塞 window.onload 事件的时间。jQuery 等待页面加载完毕的写法$(document).ready()
就会被阻塞。
最后看一个错误的写法:
1 | function(){}() |
这种写法会出现这样的错误:Uncaught SyntaxError: Function statements require a function name。
箭头函数
箭头函数是 ES6 新增特性。等同于 Java 8 支持的 lambda 表达式。
Java 8 的 lambda 表达式是对 函数式接口
进行简写。
带有
@FunctionalInterface
注解的接口叫做函数式接口
。
JavaScript 中箭头函数是对函数的缩写。
Java 8 写法:
1 | Runnable printHelloWord = () -> System.out.println("hello world"); |
JavaScript 写法:
1 | const printHelloWord = () => console.log('hello word'); |
现在请集中注意力,要说一下 JavaScript 中和此相关的坑。
以常用的 Vue 框架中函数的定义来举例,这是用 Vue 开发每天都会看到的。
1 | // 使用传统函数 |
这里涉及到 JavaScript 中 this
关键字的作用域范围。
在 JavaScript 中:
- 在任何函数体外部和对象内部,都属于全局上下文,
this
都指向全局对象(window
)。 - 在函数内部,
this
的值取决与函数被调用的方式,简单说就是谁调用了这个函数,函数内的this
就指向谁。
在 Java 中,this
关键字的作用域只有一条标准,就是谁调用就指向谁,但是因为 Java 中的函数只能通过类来调用,所以 this
就恒指向函数所在类的实例(静态方法中不能使用 this
关键字)。
看实际案例:
1 | // 1.在函数体外部使用 this |
开发套件
Node.js:https://nodejs.org/zh-cn/
JavaScript 运行环境。对标 JRE,不对标 JDK,因为 JavaScript 本身就不需要编译直接就运行。
在 JavaScript 开发的项目中使用
npm run build
仅是对项目进行压缩、优化、打包等操作,并不会有类似 Java 到 class 的编译过程。在 TypeScript 开发的项目中使用
npm run build
虽然有 TypeScript 编译为 JavaScript 的过程,但是其编译动作并不是 Node.js 完成的,而是运行在 Node.js 上的typescript
插件完成的,此插件和 TypeScript 同名,类似 JRE 中有一个名为java
的可执行文件。
前端界的包管理工具,附带在 Node.js 安装包中。NPM 和 webpack 的结合对标 Maven 或 Gradle。
webpack:https://webpack.js.org/;https://github.com/webpack/webpack
项目管理工具。NPM 和 webpack 的结合对标 Maven 或 Gradle。
sublime text:https://www.sublimetext.com/
文本编辑工具。安装包小,运行资源占用少,运行速度快。
Atom:https://atom.io/;https://github.com/atom/atom
基于 Electron 使用 JavaScript 开发的可编程文本编辑器。
Visual Studio Code:https://code.visualstudio.com/;https://github.com/microsoft/vscode
通常称 vscode,微软基于 Electron 使用 TypeScript 开发的可编程文本编辑器。因为 atom 刚开始的时候运行很慢,资源占用很大,经常崩溃,后来微软用同样的技术栈开发了 vscode。
主要框架
Vue.js:https://cn.vuejs.org/
JavaScript 或 TypeScript 语言开发,支持混合 JSX 语法。对标 Spring Framework、Spark Framework(不是 Apache Spark)。
Vue CLI:https://cli.vuejs.org/zh/
基于 Vue.js 进行快速开发的完整系统。对标 Spring Initializr。
Angular:https://angular.cn/
JavaScript 或 TypeScript 语言开发,支持混合 JSX 语法,通常使用 TypeScript。对标 Spring Boot。
Angular CLI:https://angular.cn/guide/cli-builder
Angular 命令行构建器。对标 Spring Initializr。
React:https://zh-hans.reactjs.org/
JSX 语法开发。对标 Spring Framework、Spark Framework(不是 Apache Spark)。
(JSX 是一个看起来很像 XML 的 JavaScript 语法扩展)
React CLI:https://github.com/magalhas/react-cli
React 项目快速创建工具。对标 Spring Initializr。
基础库
axios:https://github.com/axios/axios
HTTP 请求工具。对标 HttpClient、OkHttp、Spring Framework 中的 Spring RestTemplate 等。
Vuex:https://vuex.vuejs.org/zh/guide/
专为 Vue.js 应用程序开发的状态管理模式。本质是一个全局数据存储容器,从功能上对标 Redis。
Vue Router:https://router.vuejs.org/zh/
路由管理器,控制 URL 跳转视图。对标 Status 或 Spring Framework 中的 Spring MVC。
UI 组件
ElementUI:https://element.eleme.cn/
饿了么主推基于 VUE 的 PC 端后台 UI 组件
mint-ui:https://github.com/ElemeFE/mint-ui
饿了么开发的基于 VUE 的移动端 UI 组件
Ant Design of React:https://ant.design/
蚂蚁金服主推基于 React 框架的 PC 端后台 UI 组件
Ant Design Mobile of React:https://mobile.ant.design/
蚂蚁金服主推基于 React 框架的移动端 UI 组件
Ant Design of Angular:https://ng.ant.design/
蚂蚁金服维护的基于 Angular 框架的 PC 端后台 UI 组件
Ant Design Mobile of Angular:http://ng.mobile.ant.design/
蚂蚁金服维护的基于 Angular 框架的移动端 UI 组件
扩展资源
Weex:https://weex.apache.org/zh/
使用 Vue.js 来构建 Android、iOS 和 Web 应用。
React Native:https://facebook.github.io/react-native/
使用 JavaScript 和 React 编写原生移动应用。
Ionic:https://ionicframework.com/
使用 Web 技术进行智能设备 APP 开发的框架。原本只支持 Angular,现在还支持 Vue.js、React 以及脱离框架使用纯 JavaScript。
Electron:https://electronjs.org/
基于Node.js 和 Chromium 的开发套件,主要目的是支持 JavaScript、HTML 和 CSS 构建跨平台的桌面应用。
Flutter:https://flutter.cn/
Google 开源的 UI 工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动、Web、桌面和嵌入式平台,使用全新的 dart 语言。
最后我们来整体看一下前端的发展历程:
HTML
- 1980 年,「伯纳斯-李」编写了 ENQUIRE,这是万维网的前身
- 1990 年圣诞节,「伯纳斯-李」编写了全球首个网页浏览器(同时也是网页编辑器)和网页服务器
- 1991 年 8 月 6 日,万维网公共服务的首次亮相,第一个网页地址是:http://info.cern.ch/hypertext/WWW/TheProject.html
- 1995 年 11 月 24 日,HTML 2.0 发布
- 1997 年 1 月 14 日,首个完全由 W3C 开发并标准化的版本 HTML 3.2 发布
- 1997 年 12 月 18 日,W3C 发布 HTML 4.0
- 2014 年 10 月 28 日,W3C 发布 HTML 5.0
JavaScript
- 1995年12月4日, Netscape Navigator 2.0 Beta 3 更名为 JavaScript,Netscape 公司与 Sun 公司联合发布了 JavaScript 语言
- 2005年,Ajax方法诞生
- 2006年,jQuery函数库诞生
- 2009年,Node.js项目诞生
- 2013年5月,Facebook发布UI框架库React
- 2015年,vuejs发布1.0版本
- 2016年,vuejs2.x版本发布
搭建项目脚手架
本次使用 Vue.js 框架及相关生态来搭建项目脚手架。
环境准备
安装 node.js
浏览器打开 http://nodejs.org/ 下载适合自己系统的版本,双击安装即可。
设置 node.js 镜像加速
不建议用 cnpm 安装,会有各种诡异的bug。
打开命令行窗口,键入以下两行命令即可解决 npm 下载速度慢的问题。
1 | npm config set registry https://registry.npm.taobao.org |
安装 vue-cli
打开命令行窗口,键入以下命令:
1 | npm install -g @vue/cli |
输出结果如下:
1 | C:\Users\vm>npm install -g @vue/cli |
到此即安装成功,可以使用 vue --version
验证,能正确输出版本号才可以继续下一步:
1 | C:\Users\vm>vue --version |
使用 vue-cli 创建项目
打开命令行窗口,键入以下命令:
1 | vue create hello-world |
按提示选择一种项目模板然后按下回车键:
1 | Vue CLI v4.0.5 |
若选择第二项,则会继续出现如下选项:
1 | Vue CLI v4.0.5 |
一般在生产项目中,会在第一步选择 Manually select features
选项,然后在第二步按以下方式选择
1 | >(*) Babel |
我们这里选择 default
选项后等待创建完成
1 | Vue CLI v4.0.5 |
执行控制台输出的最后两行命令即可运行创建的项目。
1 | cd hello-world |
执行完毕后控制台显示如下:
1 | DONE Compiled successfully in 8183ms |
控制台显示内容包含了两个 url,任意复制其中一个 url 在浏览器打开即可看见如下界面:
到此,你已经学会了用 vue 创建项目了。
我们来认识一下这个项目包含哪些文件。
1 | node_modules -- 项目所需要的依赖库在本地的存储位置 |
src\main.js
是入口文件,src\App.vue
是整个项目的主要工作页面,其他的所有页面最终都是在 App.vue
中通过 JavaScript 脚本绘制的。
1 | <!-- src\App.vue --> |
删去多余的代码后整体文件格式如下
1 | <template> |
实操功能开发
接下来我们就开始一个简单的数据列表开发
使用原始的方式开发
这也是前端开发的本质,抛弃那些花里胡哨的工具和开发方式,回归 node.js 诞生以前的开发方式。使用此方式可以跳过以上所有环节,只需一台可以联网的电脑,任何环境都无需配置,有记事本即可开发。
第一阶段,编写一个 hello word
新建一个目录
在此目录新增文件 index.html
编辑 index.html 内容如下并保存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<html>
<head>
<meta charset="UTF-8">
<title>Vue演示</title>
</head>
<body>
<div id="app">
{{message}}
</div>
</body>
<!-- 引入 vue -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
</html>
现在用浏览器打开它,即可看见运行结果。
第二阶段,引入 ElementUI 开发一个数据列表
1 |
|
现在用浏览器打开它,即可看见运行结果。
使用工程化方式开发
我们使用前面「搭建项目脚手架」环节创建的项目来继续。
因为此项目本身就是 vue-cli 创建的,所以不需要再引入 vue 依赖,只需要添加 ElementUI 即可。运行下方命令添加 ElementUI 库。
1 | npm i element-ui -S |
在项目根目录执行上面的命令后输出结果如下:
1 | C:\Users\vm\hello-world>npm i element-ui -S |
接下来我们要开始修改代码了。
第一步
修改 hello-world\src\main.js
文件为下方内容将添加的 ElementUI 引入项目源码里。
1 | import Vue from 'vue' |
相较于修改前,添加了如下的三行代码。
1 | import 'element-ui/lib/theme-chalk/index.css'; |
第二步
将 hello-world\src\components\HelloWorld.vue
文件内容替换成以下内容
1 | <template> |
接下来我们使用以下命令运行这个项目
1 | npm run serve |
最后在浏览器打开控制台显示的访问地址
最后,如果要移除上面的 logo,删除 C:\Users\vm\hello-world\src\App.vue
文件中的 <img alt="Vue logo" src="./assets/logo.png">
即可。
参考资料
- 万维网 - 维基百科:https://zh.wikipedia.org/wiki/%E4%B8%87%E7%BB%B4%E7%BD%91
- WWW - 百度百科:https://baike.baidu.com/item/www/109924
- 蒂姆·伯纳斯-李 - 维基百科:https://zh.wikipedia.org/wiki/%E8%92%82%E5%A7%86%C2%B7%E4%BC%AF%E7%BA%B3%E6%96%AF-%E6%9D%8E
- 蒂姆·伯纳斯-李 - 百度百科:https://baike.baidu.com/item/%E8%92%82%E5%A7%86%C2%B7%E4%BC%AF%E7%BA%B3%E6%96%AF%C2%B7%E6%9D%8E
- ENQUIRE - 维基百科:https://zh.wikipedia.org/wiki/ENQUIRE
- ENQUIRE - 北城百科:https://www.beichengjiu.com/computerscience/339448.html
- WorldWideWeb - 维基百科:https://zh.wikipedia.org/wiki/WorldWideWeb
- Web - 百度百科:https://baike.baidu.com/item/web/150564
- JavaScript - 维基百科:https://zh.wikipedia.org/wiki/JavaScript
- JavaScript - 百度百科:https://baike.baidu.com/item/javascript/321142
- TypeScript - 维基百科:https://zh.wikipedia.org/zh-hans/TypeScript
- TypeScript - 百度百科:https://baike.baidu.com/item/typescript/4314718
- Java - 维基百科:https://zh.wikipedia.org/wiki/Java
- Java - 百度百科:https://baike.baidu.com/item/java/85979
- 网页浏览器 - 维基百科:https://zh.wikipedia.org/wiki/%E7%BD%91%E9%A1%B5%E6%B5%8F%E8%A7%88%E5%99%A8
- 浏览器 - 百度百科:https://baike.baidu.com/item/%E6%B5%8F%E8%A7%88%E5%99%A8/213911
- Mosaic - 维基百科:https://zh.wikipedia.org/wiki/Mosaic
- Mosaic浏览器 - 百度百科:https://baike.baidu.com/item/Mosaic%E6%B5%8F%E8%A7%88%E5%99%A8/9963015
- Internet Explorer - 维基百科:https://zh.wikipedia.org/wiki/Internet_Explorer
- Internet Explorer - 百度百科:https://baike.baidu.com/item/Internet%20Explorer
- Firefox浏览器 - 维基百科:https://zh.wikipedia.org/wiki/Firefox%E7%80%8F%E8%A6%BD%E5%99%A8
- Mozilla Firefox - 百度百科:https://baike.baidu.com/item/Mozilla%20Firefox