XMLHttpRequest: Chinh Phục Giao Thức HTTP bằng JavaScript

Bạn đã bao giờ tự hỏi điều gì xảy ra khi bạn nhập một địa chỉ web (ví dụ: google.com) vào trình duyệt và nhấn Enter? Trình duyệt sẽ trải qua một loạt các bước, bao gồm tìm kiếm địa chỉ IP của máy chủ, thiết lập kết nối TCP và gửi yêu cầu HTTP để lấy nội dung trang web. Quá trình này thường diễn ra “sau màn hình”, nhưng JavaScript cung cấp cho chúng ta một công cụ mạnh mẽ để tương tác trực tiếp với giao thức HTTP: đối tượng XMLHttpRequest.

Bài viết này sẽ khám phá cách sử dụng XMLHttpRequest trong JavaScript để gửi các yêu cầu HTTP đến máy chủ. Trước khi đi sâu vào, hãy cùng tìm hiểu sơ lược về giao thức HTTP và các khái niệm liên quan.

Giao thức HTTP là gì?

HTTP (HyperText Transfer Protocol) là giao thức truyền tải siêu văn bản, nền tảng của việc trao đổi dữ liệu trên World Wide Web. Nó hoạt động dựa trên mô hình client-server, trong đó trình duyệt web (client) gửi yêu cầu đến máy chủ web (server) và máy chủ trả về phản hồi. HTTP sử dụng bộ giao thức TCP/IP để đảm bảo việc truyền dữ liệu tin cậy.

Các phương thức Request trong HTTP

HTTP định nghĩa một số phương thức request khác nhau, mỗi phương thức có một mục đích riêng. Dưới đây là một số phương thức phổ biến nhất:

  • GET: Lấy thông tin từ máy chủ dựa trên URI (Uniform Resource Identifier). Phương thức GET chỉ nên được sử dụng để truy xuất dữ liệu và không gây ra bất kỳ thay đổi nào trên máy chủ.
  • HEAD: Tương tự như GET, nhưng chỉ trả về phần header của phản hồi, không bao gồm nội dung. Thường được sử dụng để kiểm tra xem tài nguyên có tồn tại hay không hoặc để lấy thông tin về tài nguyên đó.
  • POST: Gửi dữ liệu từ client lên máy chủ, thường được sử dụng để gửi biểu mẫu, tải file hoặc tạo mới tài nguyên.
  • PUT: Thay thế dữ liệu hiện có trên máy chủ bằng dữ liệu mới được cung cấp.
  • DELETE: Xóa tài nguyên được chỉ định bởi URI trên máy chủ.
  • CONNECT: Thiết lập kết nối đến máy chủ được xác định bởi URI.
  • OPTIONS: Truy vấn các tùy chọn giao tiếp được hỗ trợ bởi máy chủ cho một tài nguyên cụ thể.
  • TRACE: Thực hiện một vòng lặp kiểm tra thông báo dọc theo đường dẫn đến tài nguyên đích trên máy chủ.

Mã trạng thái (Status Code)

Mã trạng thái HTTP là một số nguyên gồm ba chữ số mà máy chủ trả về để cho biết kết quả của một yêu cầu. Mã trạng thái được chia thành năm loại chính:

  • 1xx (Informational): Yêu cầu đã được nhận và đang được xử lý.
  • 2xx (Successful): Yêu cầu đã được xử lý thành công. Ví dụ, 200 OK có nghĩa là yêu cầu thành công và máy chủ đã trả về dữ liệu yêu cầu.
  • 3xx (Redirection): Cần thực hiện thêm hành động để hoàn thành yêu cầu. Ví dụ, 301 Moved Permanently có nghĩa là tài nguyên đã được chuyển đến một URI mới.
  • 4xx (Client Error): Yêu cầu chứa lỗi và không thể được xử lý. Ví dụ, 404 Not Found có nghĩa là tài nguyên được yêu cầu không tồn tại trên máy chủ.
  • 5xx (Server Error): Máy chủ gặp lỗi và không thể xử lý yêu cầu. Ví dụ, 500 Internal Server Error có nghĩa là máy chủ gặp một lỗi không xác định.

Gửi HTTP Request bằng XMLHttpRequest trong JavaScript

XMLHttpRequest (XHR) là một đối tượng JavaScript cho phép bạn thực hiện các yêu cầu HTTP từ trình duyệt. Điều này cho phép bạn tương tác với máy chủ web, tải dữ liệu và cập nhật nội dung trang web một cách linh hoạt mà không cần tải lại toàn bộ trang.

Lưu ý quan trọng: Vì lý do bảo mật, trình duyệt thường áp đặt chính sách “Same-Origin Policy”, ngăn chặn các yêu cầu XHR đến các tên miền khác với tên miền của trang web hiện tại. Để vượt qua hạn chế này, bạn có thể sử dụng CORS (Cross-Origin Resource Sharing) nếu máy chủ đích cho phép.

Dưới đây là ví dụ về cách gửi yêu cầu HTTP GET đến một địa chỉ (ví dụ: https://sentayho.com.vn/api/data):

var req = new XMLHttpRequest();
req.open('GET', 'https://sentayho.com.vn/api/data', true); // true cho bất đồng bộ
req.onload = function() {
  if (req.status >= 200 && req.status < 400) {
    // Thành công!
    var data = JSON.parse(req.responseText);
    console.log(data); // Xử lý dữ liệu nhận được
  } else {
    // Xảy ra lỗi
    console.log('Lỗi: ' + req.status);
  }
};
req.onerror = function() {
  console.log('Lỗi kết nối');
};
req.send();

Giải thích chi tiết

  1. Tạo đối tượng XMLHttpRequest: var req = new XMLHttpRequest(); tạo một đối tượng XHR mới.
  2. Cấu hình Request: req.open('GET', 'https://sentayho.com.vn/api/data', true); cấu hình request với các tham số sau:
    • Phương thức request: GET, POST, PUT, DELETE,…
    • URL: Địa chỉ mà bạn muốn gửi request đến.
    • true: Chỉ định request là bất đồng bộ (asynchronous).
  3. Xử lý Phản hồi (Response):
    • req.onload: Hàm callback này được gọi khi request hoàn thành thành công. Bên trong hàm, chúng ta kiểm tra req.status để đảm bảo rằng request đã thành công (mã trạng thái nằm trong khoảng 200-399). Sau đó, chúng ta có thể truy cập dữ liệu phản hồi thông qua req.responseText và xử lý nó. Trong ví dụ này, chúng ta sử dụng JSON.parse() để chuyển đổi chuỗi JSON thành một đối tượng JavaScript.
    • req.onerror: Hàm callback này được gọi nếu có lỗi xảy ra trong quá trình gửi request (ví dụ: mất kết nối mạng).
  4. Gửi Request: req.send(); gửi request đến máy chủ. Đối với phương thức GET, bạn có thể truyền null hoặc không truyền tham số nào. Đối với các phương thức khác như POST hoặc PUT, bạn sẽ cần truyền dữ liệu bạn muốn gửi trong phần body của request.

Thêm Header vào Request

Trong nhiều trường hợp, bạn cần thêm header vào request để cung cấp thêm thông tin cho máy chủ. Ví dụ, bạn có thể chỉ định kiểu nội dung (Content-Type) của dữ liệu bạn đang gửi. Sử dụng phương thức setRequestHeader() để thêm header:

req.open('POST', 'https://sentayho.com.vn/api/submit', true);
req.setRequestHeader('Content-Type', 'application/json');
req.onload = function() { ... };
req.onerror = function() { ... };
req.send(JSON.stringify({ key: 'value' })); // Gửi dữ liệu JSON

Trong ví dụ này, chúng ta đặt header Content-Type thành application/json để cho máy chủ biết rằng chúng ta đang gửi dữ liệu JSON. Sau đó, chúng ta sử dụng JSON.stringify() để chuyển đổi một đối tượng JavaScript thành một chuỗi JSON và gửi nó trong phần body của request.

XMLHttpRequest với Request Bất Đồng Bộ

Như đã đề cập ở trên, chúng ta thường sử dụng request bất đồng bộ với XMLHttpRequest. Điều này có nghĩa là trình duyệt sẽ không bị “đơ” hoặc treo trong khi chờ phản hồi từ máy chủ. Thay vào đó, request được gửi đi và mã JavaScript tiếp tục thực thi. Khi phản hồi được nhận, hàm callback đã đăng ký (onload, onerror) sẽ được gọi để xử lý kết quả.

Sử dụng request bất đồng bộ giúp cải thiện trải nghiệm người dùng, đặc biệt là đối với các yêu cầu có thể mất nhiều thời gian để hoàn thành.

Tổng kết

XMLHttpRequest là một công cụ mạnh mẽ cho phép bạn tương tác với giao thức HTTP trong JavaScript. Bằng cách sử dụng XMLHttpRequest, bạn có thể gửi các yêu cầu đến máy chủ web, nhận dữ liệu và cập nhật nội dung trang web một cách linh hoạt.

Dưới đây là tóm tắt các điểm chính:

  • HTTP là giao thức truyền tải siêu văn bản, nền tảng của việc trao đổi dữ liệu trên web.
  • HTTP định nghĩa các phương thức request khác nhau như GET, POST, PUT, DELETE, mỗi phương thức có một mục đích riêng.
  • XMLHttpRequest là một đối tượng JavaScript cho phép bạn thực hiện các yêu cầu HTTP từ trình duyệt.
  • Sử dụng request bất đồng bộ để tránh làm “đơ” trình duyệt.
  • Sử dụng setRequestHeader() để thêm header vào request khi cần thiết.

Hy vọng bài viết này đã cung cấp cho bạn một cái nhìn tổng quan về XMLHttpRequest và cách sử dụng nó để làm việc với giao thức HTTP. Để tìm hiểu sâu hơn, bạn có thể tham khảo các tài liệu trực tuyến và thử nghiệm với các ví dụ khác nhau. Chúc bạn thành công!

Tài liệu tham khảo