HTTP概述
http协议是对浏览器客户端和服务器端之间数据传输的格式规范
客户输入url,向服务器发送请求request,服务器响应客户端response,
同步与异步
在BS架构(HTTP)中同步和异步的概念和多线程是不一样的。
在HTTP中同步应该理解为请求立马响应的过程。如果请求时服务器在工作,服务器立即响应,若服务器宕机,连接直接断开,而异步就不会。
异步一般用在消息中间件中(mq消息队列),HTTP异步可以看作是请求后不用立马返回响应,甚至是无响应,请求放在队列中保存,什么时候能“消费”请求时再去响应。
AJAX的同步和异步又是什么呢?
AJAX异步类似于多线程同时地分开执行多条执行路径。
而AJAX同步执行的代码仍然是从上往下执行,
举个具体点的例子:
如在网站中图像的加载,图像可以先不加载出来先显示网页文字,这样就是异步的,而同步呢,网页会转圈圈,等所有图片加载完再显示页面
HTTP请求组成
一次请求由以下部分组成:
- 请求行
- 请求头
- 请求体
响应组成依次对应,这里不细说了。
请求行
Request URL: 请求地址
Request Method: 请求方式
Status Code: 状态码
Remote Address: 远程地址
Referrer Policy: Referrer的策略,作用就是控制请求头中referrer的内容
请求头
(如下图出现了Provisional headers are shown怎么解决? 清一下缓存就好了)
cookie、user-agent这些都是很常见的请求头。
重点是:Referer 请求来源,比如这里我是在百度网站进行的url访问,请求来源就为https://www.baidu.com/…
防盗链技术可以用Referer判断来实现。
请求体
一般是POST提交的参数
使用时间戳解决浏览器缓存不一致问题
web项目下新建一个images文件夹再随便拷两张图片,设成resources
修改下index.jsp,展示图片
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>A</title>
</head>
<body>
<img alt="" src="WEB-INF/images/2.png">
<img alt="" src="WEB-INF/images/2.png">
<img alt="" src="WEB-INF/images/2.png">
</body>
</html>
启动tomcat,打开F12
我们能发现网页中重复访问的图片,只会进行一次http请求
刷新几次,可能2.png的响应码是304,这表示浏览器从本地读取图片缓存,不确定是否有效,如果是200说明从服务器端获取的数据。
但是我测试不出来304响应码,响应码是200 OK (from memory cache),这表明也读的是缓存
需要shift+F5强制刷新,才能从服务器重新拉取图片或者JS等资源。
这样会导致缓存和服务器数据不一致问题。
所以每次新版本发布,需要在js、图片后加上时间戳防止缓存不一致问题。
比如现在我要将网站的新版本发布,那么我可以这样处理,在png后面跟上?t=时间戳,那么用户下次访问网站时,浏览器会发现请求和之前缓存得请求不一样了,就重新从服务器拉取图片。
<img alt="" src="images/2.png?t=2021-1-24">
<img alt="" src="images/2.png?t=2021-1-24">
<img alt="" src="images/2.png?t=2021-1-24">
<img alt="" src="images/2.png?t=2021-1-24">
<img alt="" src="images/2.png?t=2021-1-24">
<img alt="" src="images/2.png?t=2021-1-24">
时间戳一变化就会重新拉取数据
可以看一下各大网站得源码真实案例,很多都是这样处理的
防盗链技术
什么是防盗链?
通过我们的web项目中有图片,这时别人直接调用我们的地址,使用我们的图片,这就叫盗链。
不光是图片,还有js,视频资源等等,都有可能被盗链。
防盗链机制:判断请求头Referer来源,或者用nginx反向代理。
这里我们用Referer来做防盗链。
在项目中加一个过滤器,过滤器中判断请求头的Referer,判断请求头字段如果域名不在自己的白名单中,那么视为盗链。
那么写Servlet的Filter即可,so easy
这里Filter的urlPatterns设成/images/*,是我们的图片资源位置,那么别的网站访问我们的图片,Referer请求来源和访问目标地址就会不不匹配,我们就能判定他是盗链访问。
@WebFilter(filterName = "AntiLeechFilter", urlPatterns = { "/images/*" })
public class AntiLeechFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
//
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// 访问来源Referer 如 http://likeghee.ltd/projectName/
String referer = req.getHeader("referer");
// 请求服务器名称,Request URL的域名 如 http://likeghee.ltd
String serverName = req.getServerName();
System.out.println("referer:" + referer);
System.out.println("serverName:" + serverName);
// 访问来源为null,说明是直接通过url访问图片
// 如果访问来源包含请求服务器名称说明是自己的网站进行访问
if (referer == null || !(referer.contains(serverName))) {
// 转发
req.getRequestDispatcher("/images/error.png")
.forward(req, res);
return;
} else {
// 放行
chain.doFilter(req, res);
}
}
public void destroy() {
//
}
}
我们自己的项目当然是可以显示图片的
这时,我再建立一个项目去模拟盗用likeghee.ltd网站的图片
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<img src="http://likeghee.ltd:1551//biguanxiulian_2_war_exploded/images/4.png">
$END$
</body>
</html>
然后访问,盗用的图片返回我们服务器的error.png
我们服务器防盗链Filter的console输出log:
访问来源是来自盗用网站a.a.com,而请求的服务器域名竟然是我们的服务器,那就赶紧返回一个error.png给他,不用多谢。
HTTP响应码
响应码代表这次的响应大概是什么结果.(只是大概,并一定准确)
随便提一下吧,用到的时候自己查一下就可以了,没啥太多好说的
404 Not Found:URL地址错误
500 Internal Server Error:系统错误
402 Forbidden:服务器理解请求的含义,但没有权限执行此请求,比如请求某个服务端目录下的音视频资源
302 Found:资源临时的重定向到另一个URI中,重定向又分为软重定向和永久重定向,扯远了
502 Bad Gateway:代理服务器无法获取到合法响应。常遇见在项目正在打包,项目正在发布的时候,就会遇到502错误
重定向与转发的原理
转发和重定义的区别?
重定向:外部访问—客户端跳转,地址会发生改变,发送两次请求
转发:一般用在服务器内部进行转发,地址栏没有变化,转发的是一次请求
response.sendRedirect("new.jsp");//重定向到new.jsp
request.getRequestDispatcher("new.jsp").forward(request, response);//转发到new.jsp
重定向例子:
@WebServlet("/L")
public class LServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("/biguanxiulian_2_war_exploded/R");
}
}
@WebServlet("/R")
public class RServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("R");
}
}
访问/L会跳转到/R,地址发生改变,这是为什么呢?
重定向原理
客户端请求/L接口,服务器中调用了sendRedirect方法,服务器会向客户端返回302状态码同时返回location参数值,location是重定向的地址,表示服务器要进行重定向的操作。
客户端取到location的地址,再一次发起/R的请求。
证明:
@WebServlet("/L")
public class LServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//resp.sendRedirect("/biguanxiulian_2_war_exploded/R");
resp.setStatus(302);
resp.setHeader("Location", "/biguanxiulian_2_war_exploded/R");
}
}
我们再次去访问/L接口,仍然是做了两次请求
转发原理
客户端请求/L接口,服务端直接帮你跳转到R接口,R接口返回值给客户端。所以只有一次请求
HTTPS和HTTP
区别
超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息。
HTTP协议以明文方式发送内容,不提供任何方式的数据加密。
不安全,
如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。(因此不要轻易连接陌生wifi,别人后台可以随意抓包分析)
为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS。
为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL/TLS协议,SSL/TLS依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。
区别:
1、https协议需要到CA申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl/tls加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
HTTPS连接过程
(1) 客户端使用https访问服务器,要求与Web服务器建立SSL连接
(2) 服务器收到客户端请求后,将网站的证书信息(包含公钥)传送一份给客户端
(3) 客户端与服务器协商SSL安全等级,也就是信息加密等级,客户端根据协商好的安全等级,建立会话密钥
(4)利用网站的公钥将会话密钥加密,并发送给服务器
(5) 服务器利用私钥解密
(6)服务器利用会话密钥加密与客户端之间的通信
SSL证书认证
看我之前的博客吧,19年的,不知道现在能不能用了,腾讯云更新超快
https://blog.csdn.net/qq_19841133/article/details/102993064
长连接和短连接
http1.0 短连接
http1.1 保留短连接,默认长连接
现在都是http1.1
短连接
发送请求,三次握手建立连接,数据传输,关闭连接四次挥手
长连接
发送请求,三次握手建立连接,数据传输,不会直接关闭,保持连接,有数据继续传输数据
为什么会有长连接?
客户端经常访问服务器,三次握手次数增大,有效数据传输的内容密度降低,保持连接提升效率。
在请求头中会有Connection字段,默认是keep-alive就代表这是一个长连接请求。
长连接何时关闭?
- 配置失效心跳检测时间,服务器发送心跳包检测,再关闭连接。
- 客户端主动关闭
- tomcat服务器配置超时时间,可以配20min之类的…
长连接场景:
http1.1、rpc远程调用、dubbo、netty、移动APP消息推送
短连接场景:
调用接口,如一天调用不超过两三次的接口
写在后面:
深究不了,实在是太深了…