首先我们要知道访问网站的流程是什么?大家每天也访问。
假设大家在浏览器地址栏输入这个问题的地址。
https://www.头条.com/question/22689579
HTML 与 CSS
当自己的电脑得到一个 html页面 (图中HTTP 响应中 body 里的内容)之后,就会对它进行解析。HTML 就是一种超文本标记语言。给大家举一些实例看看:
- [img]图片[/img] 用来粘贴图片
- [url]超链接[/url] 用来粘贴地址
服务器返回给你的html文件,写的是一些代码,大概是这样的:
浏览器拿到这些代码之后,将分析渲染好页面显示出来,如果不用css,效果如下图,按照浏览器默认的样式显示出表格,超链接等。
大家有么有觉得默认样式有点ε(┬┬﹏┬┬)3……所以很多情况我们需要自定义这些样式,目前通用的样式语言就是CSS,我们用CSS写一些自定义样式的代码,之后在 HTML 文件里用一个标签把这些规定样式的 CSS 与表达内容语义的 HTML 代码链接起来,然后大家就能看到以往所谓的正常的页面,是不是很厉害呢~~~
CSS 代码的基本格式
属性:值
比如头条的分布框架排版,它的 CSS ,截图大体如下:
把第一个属性对应的代码翻译一下的话,背景图像位置偏移量(background - position)在图像距离页面内左上角水平1px垂直2px处,浏览器会规规矩矩的地实现代码要求的效果,所以当大家在页面上下滚动时,顶上那个导航条都会牢牢地黏在窗口顶部固定的位置,不发生偏移。
再讲讲其他几个属性解释一下:
- left 为240px 说明这个模块需紧贴着窗口的左240px处
- width 和 height 指定模块的宽和高
- border 指明这个模块的边界范围
换句话说,就是浏览器就会根据这些 CSS 代码,自动描绘出对应的样式。
HTML 5 与 XHTML
像语言一样,大家在网页里的 发现的HTML 代码也不一定是标准的,就好比有时候发音不太标准,别人就会去猜测你说的是什么一样,sometimes,程序猿不小心写错了一个 HTML代码,浏览器也会试图猜测这些人类原来到底想写什么,之后做出对应的处理,而这里的猜是要有一个常识做依据的。加上有些浏览器的功能不一,有的支持一些标签,有一些又不支持,还有一些混乱的情况。
为了防止大家混淆,我们要对 HTML 代码里的标签,标签how写,标签可以hava属性这些东西,建立一个符合的标准,HTML5 就是其中一个比较新的标准。其中新加了很多可以用的标签和属性,然后各大浏览器也大刀阔斧的按这个标准去实现了很多新标签和属性。
本来前端程序员要写一堆代码去实现的效果,现在浏览器都给实现了,只需程序猿写两三行,调用一下浏览器就给搞定了,十分简单,所以很多人都愿意去推广这个标准~(当然新标准也不可能是完美的,也会有一些问题,有兴趣的朋友可以去查查)
至于 XHTML,就是 HTML 的表亲,XML 和 HTML 自己的杂交系列,对语法要求十分的严格,为了兼容 XML,在语法上与 HTML 有一些不同。
JavaScript 与浏览器脚本
有了表示内容和语义的 HTML,规定样式的 CSS,得到的是静态的页面,没什么动画,虽然用 CSS 可以有一些动画,需要刷新数据才可以,这么呆板单调的网页怎么能展现我大智人种族的创造性!于是我们创造了 Javascript(JS) 来给页面添加一些动态的效果,比如头条的发表的标签,鼠标移上去会弹出一个小窗口,这个就是 JS 实现的效果啦。
浏览器都会帮大家实现一些Javascript可以用的工具(函数,对象等),只要写一些 JS 的代码,保存在 xxx.js 里,在 html 文件中用 <script>关联进来就可以用了,像上图这个效果应该就包括了
- 鼠标悬停到标签上时创建一个新的<div> 小窗口
- 用 JS 向头条服务器发送一个请求,得到这个小窗口应该显示的数据,放在这个小窗口里(这就是所谓的AJAX,不用刷新就能与服务器进行交互,更新页面的一小部分~)
浏览器拿到这样的代码,就会解析并实现出相应的效果。其实用来写浏览器脚本的,也不是非得JavaScript 不可,不过是各大浏览器都默认了:请用 JS 写这些动态效果的代码给我解析~
以上就是前端部分的内容,下面简述一下后端的东西吧> <
Web Server 和 Web Services
浏览器给服务器发一个请求,服务器不是一看就知道怎么响应的。首先这些请求和响应要有一个通用的写法,也就是要有一个协议,常用的是 HTTP 协议。
像最前面的图,服务器的响应写了一个状态码 200 OK ,是 HTTP 协议里约定俗成的一个东西,服务器写 200 OK 在响应里,表示“你请求的这个东西我有”,如果是404 Not Found,就是“你请求的这个东西我这里没有”。
HTTP 响应里还包括很多东西,比如 Content-type 表示服务器发过来的文件类型是什么(文本?动画?图片?音频?),这样发过去了人家浏览器好知道怎么展示给用户看。人家服务器怎么知道按协议要写什么东西进去呢,这就是 Web Server 干活的时候了。
形象化一下HTTP响应,大概就长这样:
再上个锤子,浏览器和服务器之间请求响应的过程大致是长这样的,右下角的那些东西就是由 Web Server 生成的(服务器脚本可以做一些改动,但这些一般是 Web Server 的份内活):
再比如说很多时候你访问一个网站,浏览器里输的地址并没有写明你请求的文件,比如这个问题的地址是:
http://www.头条.com/question/22689579
但头条的服务器其实返回了一个html给你,服务器怎么知道这个地址对应要返回什么样的 html 代码给你的?也是 Web Server 干的活。
除了浏览器输地址敲回车这种赤裸裸的访问,客户端与服务器的交互还有很多种,比如:
- 前面提到的用 JS 完成的 AJAX,有点像浏览器和服务器之间的悄悄话~
还有其他应用软件与服务器的交互,比如:
- 微信、QQ 与腾讯的服务器的交互
- 网游客户端与网游公司服务器的交互
- 搜索引擎用来搜集网页信息的程序(爬虫)与各种各样的网站服务器的交互
- 只要你知道用什么地址访问、怎样访问人家的服务器,并且有相应权限,你也可以自己写一些程序去和他们的服务器交互(比如用微博API - 新浪微博API获取微博,开发第三方应用或者做数据分析)。
从这些例子里可以看出,客户端与服务器的交互的主体、客体、载体是五花八门的:
- 服务器可以是大型机也可以是个人电脑,只要能跑相应的程序就行
- 客户端像前面举的栗子里一样,可以是各种软件,而且这些软件不一定运行在个人电脑上,也可以是手机、平板、智能穿戴设备等等
- 有时候不是传生成好的 HTML 或者其他服务器上已经有的文件,而是传输经过一定逻辑处理后生成的字符串或者其他各种封装好的数据
像前面提到的 HTML 需要有一定标准一样,为了防止混乱和鸡同鸭讲,我们又需要先对这些机器需要怎么交互达成一定共识,再让它们进行交流。人与人之间通信,需要先有一种大家都认识的写法(比如简体字/繁体字)和一种彼此都懂的语言(比如普通话/广东话)。
要让这些形形色色的机器能够通过网络进行交互,我们就需要指明一种协议(比如 HTTP/HTTPS)和一种数据封装格式(比如 HTML/XML),Web Server 提供的 Web Service,指的就是这种协议+格式的交流体系。不过 Web Service 的生态系统和 HTML 的标准不一样,用户可以选择的协议和数据封装格式更多,普通的网站访问用的 HTTP + HTML 只是其中一种,一些封闭系统内的交流还可以自己定义一个协议和格式来用(比如 QQ)。
Web Service 传输的数据再经由本地客户端(浏览器、QQ/微信,网游客户端等)的分析渲染,就能够以普通人能够理解的形式展现出来。此外还有一些 Web Service 并不是为普通用户设计的,像前面提到的微博API,是用来给程序猿进行二次开发的~
除了提供 Web Service, Web Server 还会兼顾很多功能,包括提供缓存,平衡负载,这样在访问量比较大的时候能有有条不紊地接客。常见的现成的 Web Server 有开源的 Apache、Nginx和微软的IIS,你也可以用一些工具(比如 Node.js )自己定制一个。因为 Web Server 需要比较好的性能,所以投产时用的 Web Server 通常是C/C++/Java写的,但是其实很多语言都可以写,而且配合上语言底层的优化和好的模型,其他语言写的 Web Server也可以有不错的表现。
PHP ,服务器脚本,Web Framework
开头那张图里服务器接到请求之后可以给访客发送对应的文件,但21世纪的服务器怎么可能只会“接请求-发文件”这么弱智的一招呢,人家还可以处理你上传来的文件的!还可以接受你发过来的各种请求,去操作服务器本地的文件or数据库的!要干这些事,自然服务器那边也少不了要有代码了,这些代码就是服务器脚本。前面说的 Web Service 传输的数据,主要也是由服务器脚本生成,再交由 Web Server ,按照某种协议套好整个响应的格式,返回给客户端的。
同一个网址,每个人看到的页面不一定是一样的,比如头条的网址都是
http://www.toutiao.com/
但是没登陆和登陆之后看到的东西不一样,登陆之后每个人看到的导航栏的用户信息,关注的动态,都不一样。服务器脚本可以对这些不同的状态,生成不同的页面,交给 Web Server 返回给浏览器。
知乎的主页给大家看到的 html 整体来说是差不多的,都有导航栏,左边是关注的动态,右边是广告和边栏,每一块的整体构造大同小异,只是一些地方内容有所区别。服务器脚本就是利用已知的数据,在这些因人而异的地方填入相应的内容,生成给每个人看的页面。
比如我的主页,导航栏右边的头像和名字跟别人看到的不一样,就是因为这块地方有一个放图片的标签和一个写名字的标签,服务器脚本在查询本地的数据之后给我返回的页面里的标签填了我头像的图片链接,标签里填了我的头条名,给别人的页面就填其他链接、其他名字,这样每个人看到的页面就不一样了。
PHP 就是一种常见的用来写服务器脚本的语言,其实只要是能拿来写大家传输数据的通用接口(CGI)的语言都可以用来写服务器脚本(也就是说几乎所有编程语言都可以写 = =b),只是因为现成工具的丰富程度和专攻程度不一样,所以有一些语言在写服务器端脚本的时候会比较热门。
为了方便,我们在写服务器脚本的时候,通常还会用个同语言写的 Web Framework 来处理各种细节,防御一些常见的攻击,提供跨站认证(比如用已有的微博账号注册其他网站)的接口,利用cookie处理登陆状态和用户设置,生成网页模版之类的。如果你用 C# 或者 Visual Basic 写服务器脚本,就可以用 http://ASP.NET 这个框架实现这些功能,帮你省点麻烦。不过现在不少人是反过来为了一个好用的 Web Framework 去选择它对应的服务器脚本语言的。
一个普通网站访问的过程
简单概括一下,对于我们普通的网站访问,涉及到的技术就是:
- 用户操作浏览器访问,浏览器向服务器发出一个 HTTP 请求;
- 服务器接收到 HTTP 请求,Web Server 进行相应的初步处理,使用服务器脚本生成页面;
- 服务器脚本(利用Web Framework)调用本地和客户端传来的数据,生成页面;
- Web Server 将生成的页面作为 HTTP 响应的 body,根据不同的处理结果生成 HTTP header,发回给客户端;
- 客户端(浏览器)接收到 HTTP 响应,通常第一个请求得到的 HTTP 响应的 body 里是 HTML 代码,于是对 HTML 代码开始解析;
- 解析过程中遇到引用的服务器上的资源(额外的 CSS、JS代码,图片、音视频,附件等),再向 Web Server 发送请求,Web Server 找到对应的文件,发送回来;
- 浏览器解析 HTML 包含的内容,用得到的 CSS 代码进行外观上的进一步渲染,JS 代码也可能会对外观进行一定的处理;
- 用户与页面交互(点击,悬停等等)时,JS 代码对此作出一定的反应,添加特效与动画;
- 交互的过程中可能需要向服务器索取或提交额外的数据(局部的刷新,类似微博的新消息通知),一般不是跳转就是通过 JS 代码(响应某个动作或者定时)向 Web Server 发送请求,Web Server 再用服务器脚本进行处理(生成资源or写入数据之类的),把资源返回给客户端,客户端用得到的资源来实现动态效果或其他改变。
注意这只是小网站里比较常见的模型,大网站为了解决规模问题还会有很多处理,每个环节都会有一些细微的差异,中间还会使用各种各样的工具减轻服务器的压力,提高效率,方便日常维护~
延伸阅读 —— 那些看花眼的名词
为了方便调试,很多 Web Framework 会自带一个简单的 Web Server,或者有些 Web Server 会自带一个简单的 Web Framework ,实际部署到服务器上开放使用的时候为了性能或者安全等多方面的考虑,可以把内置的 Web Server 换成其他的,比如 Apache 或者 Nginx (举个栗子,知乎用的是 Tornado 做 Framework,Server 换成了 Nginx,见知乎使用了哪些框架和开源库?)。如果是开源的东西,还可以在遵守开源协议的前提下自己改一下再用~
因为后端不像前端已经有 HTML + CSS + JS 这样的既定事实标准,服务器脚本与 Web Framework 的选择很多,所以新手会听到很多眼花缭乱的技术名词的地方多在这里~ 举一些栗子,早年常见的服务器端语言有:
- 开源的 PHP
- Sun 公司的 JSP 中使用的 Java
- 微软的 ASP 中使用的 VBScript
现在在这方面的应用热起来的语言有
- Python,对应常见的 Framework 包括知乎和Quora有用到的 Tornado(其实是自带 Framework 的 Web Server),社区很成熟的 Django (用户包括 Instagram、Pinterest)等
- Ruby,一般都用 Rails 这个 Framework,用户包括 Github、早期的 Twitter 等
- 逆天的 JavaScript,有了 Node.js 这个平台,Web Server、服务器脚本和浏览器脚本全都可以用 JavaScript 来写……Node.js上最常用的 Framework是Express
- 微软家的则跟着 http://ASP.NET 转移到了C# 或者 Visual Basic
- Erlang,擅长大规模的并发,不少游戏公司拿来写服务器,靠几十个工程师支撑几亿用户的WhatsApp也是用的这个~
几种常见的架构包括:
- LAMP = Linux + Apache + MySQL + PHP(P还可能是Python或Perl。有时候L会改成W=Windows。),也就是服务器上的操作系统是 Linux,Web Server 用 Apache,数据库用 MySQL,服务器脚本用 PHP,这些都是开源技术,网站起步时用起来的成本会比较低,所以是普通网站里非常常见的架构(虽然对于发展得很大的网站会遇到很多瓶颈),Facebook就是这种,淘宝也曾经是。
- J2EE,Java 世界的架构,通常是企业用的(银行、大型公司,.etc),比较常见地还会搭配一种 UNIX 做操作系统,Apache 做 Web Server,Tomcat 转换 JSP 到 Java 给服务器程序用(其实它也自带 Web Server),Oracle 数据库等等。不一定拿来建站,常常用来提供企业里的各种需要用到网络的业务。我们学校教务系统就是用J2EE做的=。= 淘宝现在也是从LAMP转型到了这个。关于tomcat等之前的文章也有提及环境的配置。
- http://ASP.NET,微软家的架构,通常会搭配 Windows Server 操作系统,SQL Server 数据库,IIS 做 Web Server。StackOverflow和京东(曾经)就是这个架构。
- 神奇的MEAN架构,MongoDB做数据库,Express做 Web Framework,Angular 做前端的 JavaScript 框架,Node.js 用于编写 Web Server。神奇之处在于这几个东西的语言都是 JavaScript (MongoDB的实现不是,但与外界沟通用的语言是)。因为是比较新的架构,还有待时间的考验,不过被很多人(尤其是靠 JavaScript 吃饭的前端程序猿们)热切关注。
- 一般来说重点不在技术而且在乎成本的新网站比较喜欢用 LAMP,重视安全稳定和速度的企业和机构喜欢 J2EE,想省事的网站喜欢 http://ASP.NET,比较 Geek 的网站和创业公司喜欢折腾各种 Python、Ruby、Node.js世界的东西,Google 这样现成的技术都解决不了需求的超大型网站就自己折腾解决方案。