Tầm quan trọng của giao thức HTTP
HTTP (HyperText Transfer Protocol) là giao thức tầng ứng dụng được thiết kế để hoạt động trong các hệ thống thông tin siêu media phân tán. Giao thức này quy định cách thức giao tiếp giữa client và server, cho phép trao đổi và truy xuất tài nguyên trên World Wide Web. Từ duyệt web thông thường đến phát triển các ứng dụng phức tạp, HTTP hiện diện trong mọi khía cạnh của hệ thống mạng hiện đại.
Các phương thức request trong HTTP
GET
GET là phương thức được sử dụng phổ biến nhất, phục vụ mục đích truy xuất tài nguyên từ server. Khi người dùng nhập URL vào trình duyệt hoặc nhấp vào liên kết, một GET request sẽ được gửi đi. Ví dụ, khi truy cập https://www.example.com/page?id=123, trình duyệt gửi GET request để lấy nội dung trang có id=123.
Đặc điểm quan trọng của GET là tính idempotent - việc gửi nhiều lần cùng một request sẽ cho kết quả giống nhau (giả định trạng thái server không thay đổi). Tham số được gắn vào sau URL bằng dấu hỏi ("?") và các tham số cách nhau bởi "&". Do dữ liệu hiển thị rõ trên URL, GET không phù hợp cho việc truyền thông tin nhạy cảm.
POST
POST dùng để gửi dữ liệu lên server, thường áp dụng trong tạo tài nguyên mới hoặc thực hiện các thao tác gây thay đổi trạng thái như đăng ký người dùng, nộp biểu mẫu. Khác với GET, POST đặt dữ liệu trong body thay vì URL, giúp bảo vệ thông tin khỏi việc bị lộ và không bị giới hạn kích thước nghiêm ngặt.
Các phương thức khác
Ngoài GET và POST, HTTP còn định nghĩa các phương thức như HEAD (chỉ lấy header, không trả về body), PUT (thay đổi toàn bộ tài nguyên), DELETE (xóa tài nguyên). Trong phát triển RESTful API, việc lựa chọn phương thức phù hợp giúp thiết kế endpoint rõ ràng và tuân thủ chuẩn mực.
Dưới đây là ví dụ triển khai GET và POST request sử dụng Java:
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpClientDemo {
public static void executeGet(String targetUrl) {
try {
URL url = new URL(targetUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
int status = conn.getResponseCode();
System.out.println("GET status: " + status);
if (status == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
reader.close();
System.out.println("Response: " + result.toString());
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static void executePost(String targetUrl, String payload) {
try {
URL url = new URL(targetUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
DataOutputStream writer = new DataOutputStream(conn.getOutputStream());
writer.writeBytes(payload);
writer.flush();
writer.close();
int status = conn.getResponseCode();
System.out.println("POST status: " + status);
if (status == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
reader.close();
System.out.println("Response: " + result.toString());
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
executeGet("https://api.example.com/v1/data");
executePost("https://api.example.com/v1/create", "field1=val1&field2=val2");
}
}
HTTP Status Code
Phân loại
Status code gồm 3 chữ số, thể hiện kết quả xử lý request từ server, được chia thành các nhóm:
- 1xx (Informational): Server đã nhận request, đang xử lý, ví dụ
100 Continue. - 2xx (Success): Request xử lý thành công, như
200 OK,201 Created. - 3xx (Redirection): Cần client thực hiện thêm thao tác, ví dụ
301 Moved Permanently,302 Found. - 4xx (Client Error): Lỗi từ phía client, như
400 Bad Request,401 Unauthorized,403 Forbidden,404 Not Found. - 5xx (Server Error): Lỗi xảy ra ở server, ví dụ
500 Internal Server Error,502 Bad Gateway,503 Service Unavailable.
Một số status code phổ biến
- 200 OK: Server xử lý thành công, trả về tài nguyên yêu cầu.
- 301 Moved Permanently: URL của tài nguyên đã thay đổi vĩnh viễn, client nên sử dụng URL mới.
- 400 Bad Request: Cú pháp request sai, server không hiểu được.
- 401 Unauthorized: Request thiếu thông tin xác thực hoặc thông tin không hợp lệ.
- 404 Not Found: Server không tìm thấy tài nguyên yêu cầu.
- 500 Internal Server Error: Server gặp lỗi nội bộ khi xử lý request.
Cấu trúc HTTP message
Request message
HTTP request gồm 4 phần:
- Request line: Chứa phương thức, URL và phiên bản HTTP, ví dụ
GET /index.html HTTP/1.1. - Headers: Các cặp key-value, mỗi dòng một cặp, phân tách bằng dấu hai chấm. Cung cấp thông tin bổ sung cho server như
User-Agent,Accept,Host. - Dòng trống: Phân tách header và body, gồm hai ký tự
\r\n. - Body: Chỉ xuất hiện trong các phương thức như POST, chứa dữ liệu gửi lên server.
Response message
HTTP response có cấu trúc tương tự:
- Status line: Chứa phiên bản HTTP, status code và mô tả, ví dụ
HTTP/1.1 200 OK. - Headers: Cung cấp metadata cho client như
Content-Type,Content-Length,Date. - Dòng trống: Phân tách header và body.
- Body: Chứa dữ liệu thực tế server trả về cho client.
Ví dụ HTTP request:
GET /example HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: text/html,application/xhtml+xml,*/*;q=0.8
Ví dụ HTTP response:
HTTP/1.1 200 OK
Date: Tue, 20 Jul 2021 12:34:56 GMT
Server: Apache/2.4.46
Content-Type: text/html; charset=UTF-8
Content-Length: 1234
<html>
<head><title>Example Page</title></head>
<body><h1>Hello, World!</h1></body>
</html>
Quá trình tiến hóa của HTTP
HTTP/1.0
Phiên bản đầu tiên định nghĩa mô hình request-response cơ bản. Tuy nhiên, mỗi request cần thiết lập TCP connection mới, không thể tái sử dụng kết nối, gây tốn tài nguyên khi có nhiều request.
HTTP/1.1
Giới thiệu cơ chế keep-alive cho phép thực hiện nhiều request/response trên cùng một TCP connection, cải thiện hiệu năng đáng kể. Đồng thời bổ sung các phương thức và header mới. Tuy nhiên vẫn tồn tại vấn đề HOL blocking (Head-of-Line blocking) khi request xử lý chậm làm chặn các request phía sau.
HTTP/2
Áp dụng binary framing layer, chia HTTP message thành các frame nhỏ hơn, cho phép multiplexing - nhiều request/response chạy song song trên cùng kết nối, giải quyết triệt để HOL blocking. Đồng thời hỗ trợ nén header, tăng tốc độ tải trang đáng kể, đặc biệt với các trang có nhiều tài nguyên.
HTTP/3
Xây dựng trên giao thức QUIC (Quick UDP Internet Connection), sử dụng UDP thay vì TCP. Cung cấp độ trễ thấp hơn, cơ chế kiểm soát tắc nghẽn tốt hơn và khả năng chuyển đổi kết nối. Đặc biệt hiệu quả trong môi trường mạng yếu và khi chuyển đổi giữa các loại mạng, ví dụ từ Wi-Fi sang mobile data.