Web服务器可以接收浏览器的请求,并将服务器中的web项目资源响应给浏览器,浏览器与服务器之间进行网络通信遵循HTTP协议。
一、什么是HTTP协议
超文本传输协议(HTTP,HyperText Transfer Protocol)(浏览器---->web服务器)
网络中的通信协议:
- TCP协议,基于连接的安全传输协议(客服端和服务器先建立连接,再通过连接发送数据)
- UDP协议,基于广播/分发的非安全传输协议(不建立网络连接)
HTTP超文本传输协议是运行于TCP协议的基础之上、基于请求与响应模式、无状态的应用层协议,是互联网中应用最为广泛的一种协议。
二、HTTP协议特点
①基于连接通信:当浏览器与服务器进行通信时,会首先建议网络连接,通过网络连接进行通信
- 短连接:在HTTP1.0中,浏览器向服务器发送请求,建立连接,但是在这个连接只作用于浏览器和服务器的一次请求响应,这次请求响应完成之后则断开连接。
- 长连接:在HTTP1.1中,浏览器请求与服务器建立连接、进行请求和响应之后,会等待几秒钟,在这几秒内如果浏览器有新的请求,则直接使用之前的这个连接进行请求和数据响应,如果过了几秒钟没有新的请求,则将连接断开。
②请求与响应模式:首先由浏览器向服务器发送请求,服务器再对请求进行响应,如果没有浏览器的请求服务器时不会主动向浏览器进行响应的。
③无状态:服务器不会感知同一个客户端的多次请求(就是当服务器接收到客户端请求之后,不能识别这个客户端是否请求过我)
④简单灵活:实现简便、可以传输不同类型的数据(客户端---文件\文本--->服务器)
三、HTTP协议通信规则
通信协议:客户端与服务器之间共同遵守的规则
HTTP协议是请求和响应模式,浏览器向服务器发送请求时,需要遵守HTTP请求规则,服务器对浏览器进行响应时也遵守HTTP响应规则。
1、HTTP请求规则
说明:当在浏览器中发送请求时,浏览器已经实现了HTTP请求协议,基于这个协议发送请求的。
通过浏览器查看步骤(这种方式没法看到所有的HTTP请求内容):
- 打开浏览器
- F12打开调试窗口、点击network
- 在浏览器输入网址进行访问
- 在network窗口中查看请求头信息(Request Headers)
2、通过自定义的HTTP服务器,接收浏览器请求,查看HTTP请求规则:
- 自定义HTTP服务器:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class MyHttpServer {
public static void main(String[] args) throws IOException {
//创建一个网络服务器(可以通过浏览器请求这个服务)
ServerSocket serverSocket = new ServerSocket(9999);
//当浏览器请求我这个服务器之后,就建立网络连接(socket对象)
Socket socket = serverSocket.accept();
//通过socket对象的输入流,可以读取 浏览器发送的HTTP请求
InputStream inputStream = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
//读取 浏览器发送的HTTP请求
String content = null;
while((content = reader.readLine()) != null){
System.out.println(content);
}
//暂时未对浏览器请求进行响应
}
}
- HTTP请求内容:
3、HTTP响应规则
- 自定义浏览器
import jdk.internal.util.xml.impl.Input;
import java.io.*;
import java.net.Socket;
public class MyBrowser {
public static void main(String[] args) throws IOException {
//将上一个案例中浏览器发送给 MyHttpServer的 http请求内容,发送给百度
// 1.向百度服务器发送链接请求
Socket socket = new Socket("www.baidu.com", 80);
// 2.通过链接中的输出流,将HTTP请求内容发送给百度
OutputStream outputStream = socket.getOutputStream();
PrintWriter out = new PrintWriter(outputStream);
out.println("GET /s HTTP/1.1");
out.println("Host: www.baidu.com:80");
out.println("Connection: keep-alive");
out.println("sec-ch-ua: \"Google Chrome\";v=\"95\", \"Chromium\";v=\"95\", \";Not A Brand\";v=\"99\"");
out.println("sec-ch-ua-mobile: ?0");
out.println("sec-ch-ua-platform: \"Windows\"");
out.println("Upgrade-Insecure-Requests: 1");
out.println("User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36");
out.println("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
out.println("Sec-Fetch-Site: none");
out.println("Sec-Fetch-Mode: navigate");
out.println("Sec-Fetch-User: ?1");
out.println("Sec-Fetch-Dest: document");
out.println("Accept-Encoding: gzip, deflate, br");
out.println("Accept-Language: zh-CN,zh;q=0.9");
out.println("");
out.flush();
//3.通过输入流接受百度的响应数据(HTTP响应规则)
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String responseContent = null;
while( (responseContent = reader.readLine())!=null){
System.out.println(responseContent);
}
}
}
- HTTP响应内容
- 使用自定义HTTP服务器响应浏览器请求(遵循HTTP响应规则)
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class MyHttpServer {
public static void main(String[] args) throws IOException {
//创建一个网络服务器(可以通过浏览器请求这个服务)
ServerSocket serverSocket = new ServerSocket(9999);
//当浏览器请求我这个服务器之后,就建立网络连接(socket对象)
Socket socket = serverSocket.accept();
//通过socket对象的输入流,
InputStream inputStream = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
//读取 浏览器发送的 HTTP请求
String content = null;
while( !"" .equals(content = reader.readLine())){
System.out.println(content);
}
// 自定义HTTP服务器响应浏览器
PrintWriter out = new PrintWriter(socket.getOutputStream());
out.println("HTTP/1.1 200 OK");
out.println("Connection: keep-alive");
out.println("Content-Length: 154");
out.println("Content-Type: text/html;charset=utf-8");
out.println("Date: Sun, 07 Nov 2021 17:52:42 GMT");
out.println("Location: https://www.baidu.com/");
out.println("P3p: CP=\" OTI DSP COR IVA OUR IND COM \"");
out.println("P3p: CP=\" OTI DSP COR IVA OUR IND COM \"");
out.println("Server: BWS/1.1");
out.println("X-Frame-Options: sameorigin");
out.println("X-Ua-Compatible: IE=Edge,chrome=1");
out.println("");
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>这是自定义服务器响应的页面</title>");
out.println("</head>");
out.println("<body>");
out.println("<label style='color:red'>这是自定义服务器响应的内容</label>");
out.println("</body>");
out.println("</html>");
out.flush();
out.close();
}
}
4、HTTP响应状态码
响应状态码分类
-
1xx 表示浏览器请求服务器,服务器未做任何操作
-
2xx 表示服务器正常响应,并且响应成功
-
3xx 表示服务器只对浏览器的请求进行了部分处理,通知浏览器进行下一步操作
-
4xx 表示浏览器端(客户端)错误:404、401
-
5xx 表示服务器端资源错误
常见状态码
-
200 表示响应成功
-
302 表示服务器临时重定向
-
304 表示服务器资源没有变化
-
404 访问的资源不存在
-
500 访问的服务器端资源错误