Tích hợp HTTP 103 Early Hints cho server ExpressJS
Google Chrome phiên bản 103 đã được phát hành với một loạt các tính năng mới. Một trong những tính năng đáng chú ý là sự hỗ trợ làm việc với HTTP status 103. Bài viết này sẽ đi sâu vào HTTP status 103 và cách triển khai nó cho một server nodejs viết bằng expressjs.
HTTP Status 103
103 Early hints status được mô tả bởi Mozilla Developer Network Doc như sau:
“The HTTP 103 Early Hints
information response status code is primarily intended to be used with the Link
header to allow the user agent to start preloading resources while the server is still preparing a response.”
Trình duyệt web sẽ hỗ trợ status này giống như cách chúng ta sử dụng các thẻ <link>
với thuộc tính rel=preload
, nhưng việc liệt kê những tài nguyên nào sẽ được tải trước sẽ thuộc về phía server.
Nói cách khác, khi client request để lấy một tài nguyên, server sẽ dựa tài nguyên client cần lấy, từ đó đưa ra danh sách các phần tài nguyên cần được tải trước, và ra lệnh cho client tải trước phần đó.
Theo phương thức hoạt động như vậy, nội dung ở phía client sẽ được hiển thị nhanh hơn, mang lại trải nghiệm tốt hơn cho người dùng.
Chi tiết cách làm việc với status 103
Thông thường, trình duyệt sẽ gửi một request, server sẽ nhận và xử lý request đó và trả lại với status 200. Mô hình được mô tả như hình dưới

Việc sử dụng http status 103 sẽ có thể làm giảm thời gian rendering nội dung html.
Với một server có hỗ trợ http status 103 và trình duyệt cũng hỗ trợ http status đó, khi trình duyệt gửi một request, nếu server biết có những tài nguyên cần được tải trước như là style.css
hay script.js
v.v…, server sẽ gợi ý(hint) trình duyệt tải trước những tài nguyên đó bằng cách gửi http status 103.

Early Hints chỉ làm việc với HTTP/2 và HTTP/3 và chỉ làm việc đi kèm với status 200, 301 và 304.
Để bật được tính năng này bạn cần cấu hình nó cho http server của bạn. Phần tiếp bài viết sẽ giới thiệu cách cấu hình http status 103 với server nodejs viết bằng expressjs.
Tích hợp Early Hints status cho express server
Đầu tiên, chúng ta có một http đơn giản, server sẽ trả về nội dung file index.html
khi trình duyệt truy cập tới đường dẫn /
server.js
const path = require('path');
const express = require('express');
const app = express();
app.use(express.static(path.join(__dirname, 'public')));
app.listen(3000, () => {
console.log(`Server started on 3000`);
});
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="script.js"></script>
<title>Early Hints Demo</title>
</head>
<body>
<h1>Hello World!!!</h1>
</body>
</html>
Sử dụng curl để kiểm tra response của request:
$ curl http://localhost:3000 -k -I
HTTP/1.1 200 OK
X-Powered-By: Express
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Last-Modified: Sun, 26 Jun 2022 05:08:27 GMT
ETag: W/"196-1819e694148"
Content-Type: text/html; charset=UTF-8
Content-Length: 406
Date: Sun, 26 Jun 2022 05:12:01 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Bây giờ chúng ta sẽ cấu hình để server trả về http status 103 khi truy cập vào path /
const path = require('path');
const express = require('express');
const app = express();
app.use((req, res, next) => {
console.log(req.path)
if (req.path !== '/' && req.path !== 'index.html') {
return next();
}
const CRLF = '\r\n';
res.socket.write(`HTTP/2 103 Early Hints ${CRLF}`);
res.socket.write(`Link: </style.css>; rel=preload; as=style${CRLF}`);
res.socket.write(`Link: </script.js>; rel=preload; as=script${CRLF}`);
res.socket.write(CRLF);
next();
});
app.use(express.static(path.join(__dirname, 'public')));
app.listen(3000, () => {
console.log("Listening on port 3000")
});
(Tài liệu tham khảo RFC link)
Response sau khi thêm middleware
$ curl http://localhost:3000 -k -I
HTTP/2 103 Early Hints
Link: </style.css>; rel=preload; as=style
Link: </script.js>; rel=preload; as=script
HTTP/1.1 200 OK
X-Powered-By: Express
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Last-Modified: Sun, 26 Jun 2022 05:08:27 GMT
ETag: W/"196-1819e694148"
Content-Type: text/html; charset=UTF-8
Content-Length: 406
Date: Sun, 26 Jun 2022 06:21:44 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Như bạn đã thấy, server trả về thêm thông tin với status 103 trong thời gian response, nói cho client biết cần phải load trước những tài nguyên nào. Sau đó server mới trả về với status 200.
Lưu ý: Đây chỉ là ví dụ về việc tạo ra status 103, để mã này hoạt động như mong muốn ở phía trình duyệt, server cần là server http version 2(yêu cầu https)
Lời kết
HTTP status 103 có thể giúp chúng ta tối ưu việc redering một trang html bằng cách chỉ cho trình duyệt biết phải tải những tài nguyên nào trước. Nhưng nó vẫn còn khá mới, chúng ta cần xem xét kỹ lưỡng trước khi áp dụng vào sản phẩm.