NodeJS – HTTP Server


Được đăng vào ngày 19/09/2016 | 0 bình luận
NodeJS – HTTP Server
3.67 (73.33%) 3 votes

Đối tượng HTTP Server là đối tượng chính trong một ứng dụng Node, mục đích chính của đối tượng này là lắng nghe và giao tiếp với các kết nối HTTP. Mặc dù sau này hầu hết (hoặc chắc chắn) chúng ta sẽ sử dụng một web framework khác là Express để phát triển ứng dụng vì framework này đã đơn giản hóa mọi thứ, chúng ta chỉ cần quan tâm đến việc phát triển các tính năng chứ không cần quan tâm đến mấy thứ cấp dưới như giao thức, gói tin…v.v. nhưng vì Express cũng được xây dựng dựa trên đối tượng HTTP Server nên ít nhất chúng ta cũng nên tìm hiểu qua.

Trong bài cài đặt Node, chúng ta đã viết thử một web server đơn giản như sau:

var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type' : 'text/plain'});
    res.end('Hello, World!\n');
}).listen(8124, '127.0.0.1');
console.log('Server running at http://127.0.0.1:8124');

Hàm http.createServer() sẽ tạo một đối tượng http.Server, và bởi vì đối tượng này kế thừa từ lớp EventEmitter nên chúng ta có thể viết lại đoạn code trên cho dễ nhìn hơn như sau:

var http = require('http');
var server = http.createServer();
server.on('request', function(req, res) {
    res.writeHead(200, {'Content-Type' : 'text/plain'});
    res.end('Hello, World!\n');
});
server.listen(8124, '127.0.0.1');
console.log('Server running at http://127.0.0.1:8124');

Khi sự kiện request xảy ra (tức là khi có người truy cập vào website), hàm function(req, res) {...} sẽ được gọi, hàm này có 2 tham số là reqres, trong đó req là một đối tượng lớp http.IncomingMessage, còn res là đối tượng lớp http.ServerResponse. Đối tượng req chứa thông tin của gói tin được gửi lên, đối tượng res sẽ chứa những dữ liệu trả về cho trình duyệt. Hàm listen() sẽ chạy server và lắng nghe trên cổng do chúng ta chỉ định, ở đây là cổng 8124.

Chúng ta sẽ sửa lại đoạn code trên một tí để server trả về một số thông tin khác thay vì chỉ in ra dòng chữ Hello, World như trên:

var http = require('http');
var util = require('util');
var url  = require('url');
var os   = require('os');
var server = http.createServer();
server.on('request', function(req, res) {
    var reqUrl = url.parse(req.url, true);
    res.writeHead(200, {'Content-Type': 'text/html'}); 
    var content = "";
 
    if(reqUrl.pathname === '/') {
        content += "<html>";
        content += "<head>";
        content += "<title>Hello, World!</title>";
        content += "</head>";
        content += "<body>";
        content += "<p><a href='/osinfo'>OS Info</a></p>";
        content += "</body>";
        content += "</html>";
    } else if (reqUrl.pathname === '/osinfo') {
        content += "<html>";
        content += "<head>";
        content += "<title>Operating System Info</title>";
        content += "</head>";
        content += "<body>";
        content += "<h1>Operating System Info</h1>";
        content += "<table>";
        content += "<tr><th>TMP Directory</th><td>" + os.tmpDir() + "</td></tr>";
        content += "<tr><th>Host Name</th><td>" + os.hostname() + "</td></tr>";
        content += "<tr><th>OS Type</th><td>" + os.type() + " " + os.platform() + " " + os.arch() + "</td></tr>";
        content += "<tr><th>Memory</th><td>total: " + os.totalmem() + ", free: " + os.freemem() + "</td></tr>"; 
        content += "</table>";
        content += "</body>";
        content += "</html>";
    }
 
    res.end(content);
 
});
server.listen(8124);
console.log('Listening to http://127.0.0.1:8124');

Nếu bạn đã từng làm việc với PHP thì đoạn code trên làm một số công việc tương tự như hàm sysinfo() trong PHP, module os có chức năng cung cấp các thông tin về server, nếu muốn bạn có thể tìm hiểu thêm về module này trên mạng.

Điều quan trọng hơn cần quan tâm trong đoạn code trên là phần routing, tức là phần xử lý từng đường dẫn url riêng biệt. Khi chúng ta gõ 127.0.0.1:8124 lên trình duyệt thì trình duyệt sẽ gửi một gói tin HTTP đến server và server sẽ truyền gói tin đó vào tham số req trong hàm xử lý, tham số này chứa một số thông tin có thể dùng cho việc routing là request.urlrequest.method.

Ở đoan code trên chúng ta dùng trường request.url để routing, đây là một chuỗi chứa đường dẫn phía sau địa chỉ server, ví dụ 127.0.0.1:8124 thì request.url chỉ là '/', nếu 127.0.0.1:8124/osinfo thì request.url'/osinfo'. Ngoài ra chúng ta không dùng tham số này một cách bình thường mà thay vào đó chúng ta tạo một đối tượng lớp URL bằng phương thức url.parse(), sau đó mỗi lần kiểm tra đường dẫn để trả về nội dung thì chúng ta xem trường url.pathname.

Ngoài url ra thì có một tham số chúng ta cũng hay quan tâm tới là request.method, nếu bạn đã từng làm web trước đây thì bạn sẽ biết là một yêu cầu gửi lên server thường có các kiểu method như GET, POST, PUT... ở đây chúng ta chưa đụng tới và sẽ tìm hiểu trong các bài sau.

Ngoài ra cách kiểm tra đường dẫn bằng cách so sánh chuỗi trong đoạn code trên thường không hiệu quả với các ứng dụng lớn, vì các ứng dụng lớn thường có đường dẫn rất phức tạp và có cả tham số nên thường chúng ta sẽ sử dụng các phương pháp khớp mẫu chuỗi để routing, chúng ta sẽ tìm hiểu thêm trong các bài sau.

Chạy đoạn code trên chúng ta có kết quả tương tự như sau:

capture







Trả lời


Lưu ý: bọc code trong cặp thẻ [code language="x"][/code] để highlight code.


Ví dụ:


[code language="cpp"]


    std::cout << "Hello world";


[/code]



Các ngôn ngữ được hỗ trợ gồm: actionscript3, bash, clojure, coldfusion, cpp, csharp, css, delphi, diff, erlang, fsharp, go, groovy, html, java, javafx, javascript, latex, matlab, objc, perl, php, powershell, python, r, ruby, scala, sql, text, vb, xml.

Thư điện tử của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *