前端历史 --- 从HTML静态文件到前后端分离
- 1. 静态HTML
- 2. 动态HTML --- 服务器端渲染
- CGI --- Common Gateway Interface
- servlet
- ASP, JSP, PHP
- 服务器端渲染(SSR)
- 3. 前后端分离 --- 客户端渲染
- JavaScript
- Ajax --- Asynchronous Javascript And Xml.
- 客户端渲染
1. 静态HTML
- 在上个世纪的1989年,欧洲核子研究中心的物理学家Tim Berners-Lee发明了超文本标记语言(HyperText Markup Language),简称HTML,并在1993年成为互联网草案。从此,互联网开始迅速商业化,诞生了一大批商业网站.
- 最早的HTML页面是完全静态的网页,它们是预先编写好的存放在Web服务器上的html文件。浏览器请求某个URL时,Web服务器把对应的html文件扔给浏览器,就可以显示html文件的内容了
- 问题是 如果要针对不同的用户显示不同的页面,显然不可能给成千上万的用户准备好成千上万的不同的html文件,所以,服务器就需要针对不同的用户,动态生成不同的html文件
2. 动态HTML — 服务器端渲染
CGI — Common Gateway Interface
- 为了动态生成不同的HTML文件, 最直接的想法就是利用编程语言 (比如C++, C) 编写程序来处理客户端发来的表单数据, 并将需要的数据拼接成HTML字符串输出给浏览器. 这种应用程序被称为 CGI脚本
- CGI是一个标准化的协议,能够使应用程序(通常称为CGI程序或CGI脚本)同web服务器和客户端进行交互。CGH程序能够用Python、PERL、 Shell, C或C++等语言来实现
- CGI是Web服务器和一个独立的进程之间的协议,它会把HTTP请求Request的Header头设置成进程的环境变量,HTTP请求的Body正文设置成进程的标准输入,进程的标准输出设置为HTTP响应Response,包含Header头和Body正文
- 缺点:
- 使用CGI会调用服务器端的一个应用程序(CGI脚本)用来处理请求并返回静态页面, 但是有安全性问题, 因为这样外部请求可以直接执行服务器上的程序, 如果出现恶意请求, 可能会让服务器执行本来不想运行的程序.
- 每一个请求会建立一个进程运行CGI脚本程序, 当请求量过大时服务器会过载,所以不能应对高并发的情况
servlet
- Java为了实现在服务器上动态的生成内容, 再把静态内容返回,引入了 servlet
- servlet提供了对整个Java API的完全访问, 并且提供了一个完备的库可以处理HTTP (extend Httpservlet)
- servlet 运行过程:
- 得到客户端发来的请求信息(request)
- 根据客户端请求信息调用service完成业务逻辑
- 使用out.println()将结果和HTML拼接在一起写入reponse
- 缺点
- 在这个黑暗岁月,通常情况是美工写好html静态页面后,丢给Java程序员。Java程序猿在Servlet中调用Service拿到数据后,逐句复制html静态页面上的html语句到Servlet的中,根据情况将后端的数据与html片段拼接在一起,然后以诸如
out.println("<span>用户名是:"+user.name+<"/span>");
的方式疯狂输出- 按这种方式,要想拼接数据并完整输出一个html页面,没个几百上千行out.println()是不可能的。所以基本上敲完两个页面两根手指就麻了。
ASP, JSP, PHP
ASP 和 PHP
- 同时期的PHP,http://ASP.Net就优秀得多了. 它们选择在“html页面”中嵌入相应语言来引入动态数据,避免了手动拷贝html片段输出的尴尬局面.
- PHP 和 ASP 直接在html语句中写入动态数据
JSP
- 面对PHP和ASP带来的压力, Java创造了JSP
- JSP文件里可以写HTML代码,还可以把Java代码内嵌在JSP页面中,很方便地把动态数据渲染成静态页面.
<%@ page import="com.itheima.pojo.Brand" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
// 查询数据库
List<Brand> brands = new ArrayList<Brand>();
brands.add(new Brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
brands.add(new Brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
brands.add(new Brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));
%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="button" value="新增"><br>
<hr>
<table border="1" cellspacing="0" width="800">
<tr>
<th>序号</th>
<th>品牌名称</th>
<th>企业名称</th>
<th>排序</th>
<th>品牌介绍</th>
<th>状态</th>
<th>操作</th>
</tr>
<%
for (int i = 0; i < brands.size(); i++) {
Brand brand = brands.get(i);
%>
<tr align="center">
<td><%=brand.getId()%></td>
<td><%=brand.getBrandName()%></td>
<td><%=brand.getCompanyName()%></td>
<td><%=brand.getOrdered()%></td>
<td><%=brand.getDescription()%></td>
<td><%=brand.getStatus() == 1 ? "启用":"禁用"%></td>
<td><a href="#">修改</a> <a href="#">删除</a></td>
</tr>
<%
}
%>
</table>
</body>
</html>
- JSP本质是一个Java servlet
- JSP中直接写HTML代码和Java代码,后期JSP编译成一个Servlet,通过Java代码获取后台数据后拼接到HTML片段中,最终通过out.println()输出
- JSP编译成Java类之后会继承HttpJspBase,而HttpJspBase间接实现了Servlet接口。所以可以说,index.jsp被翻译后的Java类也是一个Servlet,所以JSP本质也是一个Servlet。
- 真相:为了不让Java程序员一行行复制HTML代码到Servlet里,SUN公司干脆让Java程序员直接把HTML写在了Servlet里!但是毕竟SUN还没有那么明目张胆,好歹让这个Servlet伪装了一把,打扮成JSP,然后跟程序员说:看,我搞了个JSP,这家伙可牛逼了,你能在上面同时写HTML和Java代码哦。 得了吧,等你写完JSP,回头访问时,Tomcat就把这个JSP翻译成Servlet,原先写在JSP里的HTML代码就自动放在了out.println()里啦!相当于程序帮我做了“逐行复制HTML代码到Servlet”这一步。(想起来手就麻!)
服务器端渲染(SSR)
- 以上这些技术全部是服务器端渲染
- 服务端将HTML文本组装好,并返回给浏览器,这个HTML文本被浏览器解析之后,不需要经过 JavaScript 脚本的执行,即可直接构建出希望的 DOM 树并展示到页面中,最后将这些静态标记"激活"为客户端上完全可交互的应用程序
优点:
- 动态展示的数据在页面的源代码中可以看见,有利于SEO优化推广(有利于搜索引擎的收录和抓取)
- 从服务器端获取的结果已经是解析渲染完成的了,不需要客户端再去解析渲染了,所以页面加载速度快(前提是服务器端处理的速度够快,能够处理过来),所以类似于京东,淘宝这些网站,首屏数据一般都是由服务器端渲染的
缺点:
- 如果页面中存在实时更新的数据,每一次想要展示最新的数据,页面都要重新加载一次,这样肯定不行,非常耗性能
- 都交给服务器端做数据渲染,服务器端的压力太大,如果服务器处理不过来,页面呈现的速度更慢
- 这种模式不利于开发,(开发效率低)
3. 前后端分离 — 客户端渲染
JavaScript
- 创建JavaScript的初衷是帮助开发人员动态的修改页面, JavaScript可以通过修改HTML的DOM结构和CSS来实现一些动画效果,而这些功能没法通过服务器完成,必须在浏览器实现, 以便为客户提供更丰富的体验.
Ajax — Asynchronous Javascript And Xml.
- 因为JavaScript可以修改HTML的DOM结构, 那么我们可以利用JavaScript局部的渲染HTML页面. 这样服务器端只需要传递少量的数据就可以了, 而不用每次请求都重新渲染页面然后发给前端
- 同步提交:当用户发送请求时,当前页面不可以使用,服务器响应页面到客户端,响应完成,用户才可以使用页面。
- 异步提交:当用户发送请求时,当前页面还可以继续使用,当异步请求的数据响应给页面,页面把数据显示出来 .
- 在Ajax的帮助下, 我们可以实现前后端分离. 也就是前端使用HTML+CSS编写模板,使用XMLHttpRequest向后端请求数据, 前端再使用JavaScript解析数据然后渲染
- 这就是客户端渲染
客户端渲染
优点
- 我们可以根据需求,任意修改页面中的某一部分内容(例如实时刷新),整体页面不刷新,性能好,体验好(所有表单验证,需要实时刷新的等需求都要基于AJAX实现)
- 有利于开发,提高开发效率
- 前后端的完全分离,后台不需要考虑前端如何实现,前端也不需要考虑后台用什么技术,真正意义上实现了技术的划分
- 可以同时进行开发:项目开发开始,首先制定前后端数据交互的接口文档(文档中包含了,调取哪个接口或者哪些数据等协议规范),后台把接口先写好(目前很多公司也需要前端自己拿NODE来模拟这些接口),客户端按照接口调取即可,后台再去实现接口功能即可
缺点
- 不利于SEO优化:第一次从服务器端获取的内容不包含需要动态绑定的数据,所以页面的源代码中没有这些内容,不利于SEO收录,后期通过JS添加到页面中的内容,并不会写在页面的源代码中(是源代码不是页面结构)
- 交由客户端渲染,首先需要把页面呈现,然后在通过JS的异步AJAX请求获取数据,在进行数据绑定,浏览器再把动态增加的部分重新渲染,无形中浪费了一些时间,没有服务器端渲染页面呈现速度快