Thứ Năm, 21 tháng 6, 2012

Kỹ thuật Web: Giao tiếp với người dùng. Phần 1

Kỹ thuật Web: Giao tiếp với người dùng. Phần 1

Mức độ khó: 2
Sau ứng dụng "Hello World" đầu tiên cho lập trình Web với bất kì một ngôn ngữ nào, điều tiếp theo bạn cần làm là tìm cách giao tiếp với người dùng (nhận dữ liệu từ người dùng).
Bài viết này nhàm cung cấp một số kiến thức chung cho bạn, không hề xoáy mạnh vào bất kì ngôn ngữ nào.


Giải thích một số thuật ngữ:

Server: máy chủ đặt chuơng trình web của bạn.
Client: trình duyệt - máy của người dùng nói chung.
Request: Hiểu theo nghĩa một yêu cầu truy vấn.
Response: Câu trả lời truy vấn.

Nội dung bài viết:

Khi viết một chuơng trình dòng lệnh cơ bản nhất trên C/C++/C#... với các câu lệnh như sprintf(), std::cout <<, Console.Write()... đây là những cách "Output" thông tin ra môi trường dòng lệnh để giao tiếp với người dùng. Với lập trình Web mọi chuyện liên quan tới "Output" cũng chỉ đơn giản như thế. Có chăn text output của chúng ta đuợc markup, ví dụ khi muốn in ra một dòng text đuợc tô đậm và in nghiên (gọi là rich-text) ta đơn thuần in ra 1 dòng text (plain-text) có nội dung như sau: "<b><i>text</i></b>". <b>, <u> gọi là các thẻ markup. Có khá nhiều thẻ markup, và một designer cần thông thạo việc sử dụng các thẻ này (kèm với một số thứ khác cũng không ít quan trọng) để trình bày thông tin một cách sinh động. Một programmer không cần quan tâm về vấn đề này nhiều lắm, chỉ cần đủ dùng (Phần sau sẽ nói về các thẻ trong việc nhận thông tin).

Cụ thể thì một Request trong giao thức HTTP là gì? Để trả lời câu hỏi này một cách chính xác sẽ rất dong dài và liên quan rất nhiều tới kiến thức mạng máy tính. Một cách hiểu nôm na đủ cho chúng ta ở giai đoạn này thì: Mỗi khi ta click vào 1 đường dẫn, một nút submit, hay nhập 1 tên miền vào thanh đại chỉ và Enter (nói chung bất kì hành động nào làm cho cái Icon loading của trình duyệt họat động), là khi đó trình duyệt đã giúp ta gửi 1 vài thông tin tới server. Những thông tin đó có thể bao gồm username, password mà ta điền vào các textbox, và luôn luôn kèm theo một vài thông tin mặc định.
Trình duyệt Google Chrome có chức năng để ta theo dõi các thông tin này (sau này cả FireFox và IE mặt định đều có). Để bật chức năng này, các bạn nhấp chuột phải, chọn Inspect Element, chọn Tab Network, sau khi mở tap đó xong, hãy thử truy cập vào http://blog.open-vn.org/. Xem hình:

Mỗi một dòng trong bảng thông tin này là 1 request tới server. Sao lại nhiều thế? Ta chỉ trực tiếp gữi request tới trang chủ của blog.open-vn.org, nhưng khi trang chủ load, nó sẽ tự động gửi thêm các yêu cầu tới các file ảnh chẳn hạng (1 trang web là tập hợp của khá nhiều các file css, js, ảnh...). Ngay tại phần này ta đã có 1 số thông tin về Request và Response.
Method: Phuơng thức thực hiện truy vấn. Có 2 kiểu chính GET và POST (ngoài ra còn có nhiều kiểu phụ như HEAD, POST, PUT nhưng ta chưa cần quan tâm).
Status: Mã trạng thái trả về. Có khá nhiều mã trạng thái, ví dụ 200 có nghĩa là bình thường - ok, 404 là mã không tìn thấy nội dung yêu cầu, 500 là lỗi gì đó do nội tại server gây ra...
Type: kiểu file trả về.
Initiator: Nguồn khởi tạo. Như đã nói, trang index của open-vn.org có thể gọi một số file khác, vậy trang index là ngồn khởi tạo của các file nó gọi.
Size: con số in đậm là lưu lượng thông tin trả về của Response Header, con số in mờ cụa thể là cái gì thì mình không biết chắc, nhưng đoán là tổng cộng lưu lượng của cả truy vấn chính này.
Time: con số in đậm là tổng thời gian để trình duyệt ngừng load, con số in nghiên là khảon thời gian chờ. Thời gian chờ + thời gian load = tổng thời gian.
Tiếp theo hãy click vào url của chúng ta để xem một chút chi tiết.

Ở đây các bạn sẽ nhận thấy một số thông tin mà mình đã giải thích, còn lại tất cả đều thuộc vào 2 phần đó là Request HeaderResponse Header, Bởi vì chúng ta chưa hề có nhu cầu gửi kèm bất cứ thông tin gì khác cho server nên sẽ không có Request Body trong trường hợp này (sẽ sớm có trong phần sau), về phần Response Body, các bạn xem trong tab Response.
Hãy để ý và tìm dòng chữ mở "View source" kế bên Request Header, click vào bạn sẽ thấy nội dung chính xác mà trình duyệt gửi đi, một đọan plain-text gồm dòng thể hiện nhiều phần thông tin (không phải phần nào cũng bắt buộc có), cũng không phải thông tin gì đuợc gửi tới server đều nằm trong đây. Ví dụ IP máy client cũa sẽ đuợc gửi đi - HTTP là giao thức dựa trên TCP/IP nên điều này là tất nhiên. Tiếp theo mình sẽ phân tích vài dòng mà mình hiểu ý nghĩa của nó:
Từng dòng có nhiệm vụ báo trước cho server biết client cần gì, tất nhiên server thường làm theo yêu cầu, lưu ý là thường chứ không phải bắt buộc. Bây giờ hãy xem bài viết phân chia mức độ khó dễ của chúng tôi và thực hiện theo dõi tab Network, cả 1 đạon, quan trọng nhất là 2 dòng:
GET /2012/06/muc-o-kho-de-cua-cac-bai-viet.html HTTP/1.1
Dòng này gồm 3 phần: Method GET, RequestURI /2012/06/muc-o-kho-de-cua-cac-bai-viet.htmlProto HTTP/1.1
Quan trọng nhất trong 3 phần này là phần RequestURI, nó cho server biết ta cần tài nguyên (một trang HTML, ảnh, nhạc...) nào trên server, tùy theo server lập trình như thế nào, nó sẽ trả về một tài nguyên nào đó dựa trên RequestURI và các phần khác của Request Header (ví dụ cùng 1 RequestURI nhưng 2 Medthod khác thì server cũng có thể trả về 2 nội dung khác nhau, tùy chúng ta - những lập trình viên quyết định).


Làm thế nào để gửi một Request Body? Tại sao lại có nhu cầu này?
Ở phần trước chúng ta chỉ đề cập tới những thông tin đuợc trình duyệt mặt định gửi đi, nhưng đa số các bài toán thực tế luôn cần những thông tin dược điền từ người dùng chẳn hạn. Để ví dụ, tiếp tục bật Tab Network hữu ích của chúng ta, gõ vào ô tiềm kiếm của blog.open-vn.org bất kỳ nội dung gì, từ "web" chẵn hạng, và enter. Bạn sẽ đuợc chuyễn tới 1 trang có địa chỉ http://blog.open-vn.org/search?q=web, xem chi tiết request này, ngoại trừ 2 phần Request Header và Response Header, chúng ta còn có 1 phần gọi là Query String Parameter khóa q có giá trị là web. View source của request header, bạn sẽ thấy /search?q=web nằm gọn trong dòng đầu. Đương nhiên bạn có thể dùng một URI có cấu trúc khác /search/q/web hoặc đơn giản /search/web, nhưng người ta thường dùng cú pháp query string để dễ dàng cho việc tách dữ liệu từ URI, hơn nữa trong 1 số chuơgn trình web-server có khả năng quản lí file tĩnh(ví dụ khi tru cập vào trang example.com/foo/bar.html là ta đang yêu cầu 1 file có tên là bar.html đặt trong thư mục /foo), cú pháp truy vấn trên giúp server dễ dàng hiểu đuợc đâu là ta yêu cầu nội dung tĩnh hay động(ví dụ /topic.php?id=1 sẽ có nội dung khác với /topic.php?id=2)
Trường hợp các URI có dạng "/topic.php?id=1" chắc hản các bạn đã gặp rất nhiều, nó thường xuất hiện ở dạng các link bài viết, ngùơi dùng chỉ việc click vào và được chuyễn tới trang cần đọc. Đó, trong lập trình cũng gọi là 1 bài toán, "bài toán chuyễn hướng nguời dùng tới nội dung quyết định bởi query string parameter", nhưng một bài toán "tính tổng 5 số nguyên" mà giải bằng phuơng pháp này sẽ không hay chút nào. "tinhtong?a=1&b=2&c=3&d=4&e=5" (để truyền nhiều tham số cùng lúc ta dùng kí tự &). Chắc chắn người dùng không hề muốn phải nhìn vào cái mớ bòng bong này để thay đổi các giá trị trong bài toán của họ, điều ta cần là một giao diện thân thiện hơn, lúc này lại cần tới sự xuất hiện của các thẻ HTML, xem đoạn code ví dụ:

<form name="input" action="/tinhtong" method="get">
A: <input type="text" name="a" value="1" /><br />
B: <input type="text" name="b" value="2" /><br />
C: <input type="text" name="c" value="3" /><br />
D: <input type="text" name="d" value="4" /><br />
E: <input type="text" name="e" value="5" /><br />
<input type="submit" value="Submit" />
</form> 

Lưu đoạn code trên với tên "vidu01.html" (dùng notepad trên windows hoặc gedit trên ubuntu để lưu) mở file đó bằng trình duyệt, sẽ trả về kết quả như sau:
=========================================
A:
B:
C:
D:
E:
=========================================
hãy click và xem URI trình duyệt đã tự động tạo cho bạn.
Lưu ý: đừng mong có kết quả trả về, đây chỉ là 1 ví dụ về cách encode url với HTML form.

Cách thức truy vấn này mọi thông tin trong request body có thể nhìn thấy trên RequestURI, ta tạm hiểu đây là phuơng thức GET. Không phải lúc nào cũng tốt, một ví dụ ngu ngốc là dùng để đăng nhập, chắn chắn không có một lập trình viên nào dùng phuơng thức GET cho hệ thống đang nhập. Thử tưởng tượng với 1 URI chứa "/login?name=nick&pass=01912031023", bạn không thể bảo mật thông tin của mình với chính người đứng sau lưng bạn, đừng nói tới các hacker chuyên nghiệp có thể lợi dụng sơ hở này như thế nào.
Để khắc phục sơ hở trên, cũng như nhằm phục vụ một số mục đích đặt biệt mà sau này các bạn sẽ tự khám phá, các nhà khoa học phát triễn ra HTTP, HTML đã đưa ra một Method khác gọi là POST, với ví dụ trên, hay thay đổi đoạn method="get" bằng method="post" và tự tìm hiểu điểm khác biệt của chúng.

Bài viết này có thể dừng tại đây, bạn chắc hẳn đã nắm đuợc 1 phần về cách gửi các request tới server, phần tiếp theo chúng tôi sẽ nói về phương pháp truy cập tới các thông tin đã được gửi để xử lý và phản hổi trên Golang và PHP.

2 nhận xét:

  1. post bảo mật những thông tin gửi đi, còn get thì không, nhưng nếu k cần bảo mật thì có thể xài get, mà get thì ít ng xài hơn post vì k có tính bảo mật

    Trả lờiXóa
  2. Nói câu thứ nhất là đủ rồi skypdong à. =)) Mà chắc là post bảo mật không. Từ baỏ mật ở đây có nghĩa là gì. Là không lộ thông tin phải không. Như thế thì chưa chắc =))

    Trả lờiXóa