HTTP2
一、HTTP协议基础
HTTP(HyperText Transfer Protocol)是一种非常重要的应用层协议,用于在Web浏览器和服务器之间传输数据。基于TCP协议,它解决了在一个TCP连接中传输多个HTTP请求/响应时,应用程序如何区分完整应用层数据包的问题。
二、报文格式
1. 请求报文
- 首行:包含方法(如GET、POST等)、URL、版本号(如HTTP/1.1)。例如: GET https://www.sogou.com/ HTTP/1.1 。
- 请求头(header):包含一系列键值对,如 Host: gitee.com 、 User - Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 等,用于描述请求的相关信息。
- 空行:用于分隔请求头和正文。
- 正文(body):有的请求没有body,如GET请求一般没有;有body的请求(如POST)通过body向服务器传递数据 。
2. 响应报文
- 首行:包含版本号、状态码(如200 OK)。例如: HTTP/1.1 200 OK 。
- 响应头(header):同样是键值对形式,如 Content - Length: 168581 、 Content - Type: text/html; charset=utf - 8 等,描述响应的相关信息。
- 空行:分隔响应头和正文。
- 正文(body):大多数情况下存在,包含服务器返回的数据。
三、URL(Uniform Resource Locator)
URL是资源定位符,用于定位网络上的某个资源。格式为:协议名://服务器IP(域名):端口号/带层次的路径?key=value&key=value#片段标识符 。例如: https://www.sogou.com/ 。
四、HTTP方法
1. 常见方法
- GET:从服务器获取某个资源,一般没有body,通过路径/query string传递数据。例如在浏览器地址栏输入url触发GET请求,HTML间接加载其他资源(CSS、JS、图片等)时也会触发GET请求。
- POST:向服务器上传资源,带有body,通过body向服务器传递数据,常用于登录、上传文件等场景 。例如: POST https://gitee.com/login HTTP/1.1 ,body提交用户名和密码。
- PUT:向服务器上传资源(文件),与POST类似。
- DELETE:删除服务器的资源,一般不带body,通过query string传递数据。
2. 方法对比
- 幂等性:GET官方建议实现成幂等的,POST无要求。幂等意味着同样的请求多次执行,结果是一样的。
- 可缓存性:GET如果实现幂等,结果可缓存;POST不实现幂等,一般不能缓存。
- 传输数据量:GET请求的URL存在长度限制(不同浏览器/服务器实现不同),标准文档未明确限制;POST传输数据量理论上无此限制。
- 数据类型:GET通过query string只能传输文本(可通过urlencode处理特殊字符);POST通过body可传输文本和二进制数据 。
五、Content - Type
常见的Content - Type有:
1. text/html :表示HTML文档。
2. text/css :表示CSS样式表。
3. application/javascript :表示JavaScript脚本。
4. application/json :表示JSON格式数据。
5. image/png 、 image/jpg :表示图片资源。
浏览器/服务器根据Content - Type的值决定如何处理body中的数据。如果请求/响应有body但没有Content - Type或者Content - Length,是不规范的。
六、User - Agent
User - Agent用于标识用户使用的浏览器/系统等信息。例如: User - Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 ,可以从中解析出操作系统版本(Windows NT 10.0,64位系统 )、浏览器内核版本(AppleWebKit/537.36 )、浏览器版本(Chrome/135.0.0.0 )等信息。网站可根据User - Agent判定用户设备类型(PC端或移动端 ),提供不同版本的页面。
七、Restful风格的API设计
1. 设计规范
- 通过请求中的方法表示不同语义,如GET表示查询、POST表示新增、PUT表示修改、DELETE表示删除。
- 通过URL的路径表示操作的资源。
- 请求和响应携带的数据尽量是JSON格式。
- 通过HTTP响应的状态码表示失败的原因。
2. 作用:
编写服务器提供HTTP API时,遵循Restful风格可使API设计更规范、统一,便于他人调用。
代码示例(以Java为例)
1. 发送GET请求
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpGetExample {
public static void main(String[] args) {
try {
URL url = new URL("https://www.example.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
} else {
System.out.println("GET request not worked");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
2. 发送POST请求
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpPostExample {
public static void main(String[] args) {
try {
URL url = new URL("https://www.example.com/login");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
String postData = "username=exampleUser&password=examplePassword";
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(postData);
wr.flush();
wr.close();
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
} else {
System.out.println("POST request not worked");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
以上代码示例展示了如何使用Java的标准库发送GET和POST请求。在实际应用中,还可以使用更便捷的HTTP客户端库,如Apache HttpClient、OkHttp等