Basic HTTP (1.0)

  โดย  ประดับเก่ง

 
เกริ่นนำ
ถ้าพูดถึง protocol ที่ใช้ในการติดต่อสื่อสารระหว่าง Web Browser และ Web Server แล้วหลายคนจะต้องนึกถึง HTTP protocol แน่นอน. HTTP เป็น protocol ที่ใช้สำหรับ World Wide Web โดยใช้คอนเซ็ปของ client-server เป็นหลัก หลักการทำงานพื้นฐานของ HTTP คือการส่งข้อความจาก client ไปยัง server เพื่อทำการตีความ หลังจากนั้น server จะทำการส่งข้อความซึ่งเป็นผลจากการตีความกลับมายัง client โดยทั่วไปการส่งข้อความระหว่าง client และ server มักใช้ byte stream เป็นหลัก แต่ HTTP เป็น protocol ที่ถูกออกแบบมาเพื่อให้ใช้งานง่ายแต่มีประสิทธิภาพ ดังนั้นการส่งเดต้าแบบ text stream จึงถูกนำมาใช้แทน
บทความนี้ตั้งใจที่จะนำเสนอคอนเซ็ปอย่างง่ายของ HTTP protocol ดังนั้นเวอร์ชั่นที่ใช้ในบทความนี้จะเป็น HTTP1.0 (ปัจจุบันเริ่มมีการใช้ HTTP 1.1 กันอย่างกว้างขวาง แต่ตัว HTTP1.1 เองก็ยังตั้งอยู่บนพื้นฐานของ HTTP1.0) ความเข้าใจในหลักการทำงานขั้นพื้นฐานของ HTTP จะช่วยให้ผู้อ่านสามารถเขียน Server Side Application เช่น Servlet, JSP, Cgi, ASP, PHP, Cold Fusion ฯลฯ ได้อย่างมีประสิทธิภาพมากขึ้น อย่างไรก็ตามสำหรับผู้ที่อยากเขียน Web Browser, Web Server หรือ Web Crawler อย่างง่าย ๆ (หรือยาก) บทความนี้ก็เหมาะจะเป็นพื้นฐานในการเตรียมพร้อมก่อนที่จะอ่าน HTTP Specification1.1 ในส่วนของรายละเอียดต่อไปเช่นกัน

What is HTTP?
HTTP มาจากคำว่า Hypertext Transfer Protocol ซึ่งเป็น protocol ที่ใช้ในการส่งเดต้าต่าง ๆ ในโลกของ World Wide Web.  เดต้าต่าง ๆ เหล่านี้โดยทั่วไปมักจะถูกเรียกว่า Resource โดย Resource เหล่านี้อาจจะเป็นไฟล์ เช่น HTML ไฟล์, image ไฟล์ หรือคำสั่งต่าง ๆ (Query String) เช่น คำสั่งที่ส่งไปที่ Cgi โปรแกรมหรืออาจจะ binary stream ในกรณีของการ download/upload ไฟล์ หรืออาจจะเป็นสิ่งอื่น ๆ อีกมากมายตามแต่จะกำหนดขึ้น
HTTP เป็น protocol ที่อยู่ในส่วนของ Application Layer ใน protocol stack โดยเดต้าต่าง ๆ จาก Layer นี้จะถูกจากส่งผ่านไปยัง Layer อื่น ๆ ที่ต่ำกว่าซึ่งส่วนหนึ่งในนั้นก็คือ TCP/IP protocol นั่นเอง (เราจะไม่กล่าวถึงรายละเอียดของ protocol stack ในที่นี้)

HTTP เป็น network protocol ที่ใช้หลักการของ client-server model ในการติดต่อสื่อสารซึ่งหลักการทำงานอย่างคร่าว ๆ มีดังนี้
1. HTTP Client จะทำการสร้างคอนเนคชั่นไปหา HTTP Server ซึ่งโดยทั่วไปจะผ่านทาง socket ของ TCP/IP
2. หลังจากนั้น HTTP Client จะทำการส่งคำสั่ง (request) ซึ่งอยู่ในรูปของ message ไปให้ HTTP Server เพื่อทวงถามถึง resource ที่ต้องการ
3. HTTP Server จะทำการตีความคำสั่งที่ได้และส่งผล (response) ซึ่งเป็น resource ที่ HTTP Client ต้องการกลับมา (ผลที่ส่งกลับมาจะเป็นลักษณะของ message คล้ายกับ requet ของ HTTP Client ที่ส่งมาให้ HTTP Server)
4. หลังจากที่การส่ง response เสร็จสิ้น, HTTP Server จะทำการปิดคอนเนคชั่นที่มาจาก HTTP Client
5. ในกรณีที่ HTTP Client ต้องการ resource อื่น ๆ, HTTP Client จะต้องทำการสร้างคอนเนคชั่นใหม่และส่งคำสั่งไปหา HTTP Server อีกครั้ง
จากหลักการข้างต้นจะเห็นว่าการติดต่อสื่อสารระหว่าง Client และ Server จะเป็นลักษณะครั้งต่อครั้ง ในทาง network เราเรียกการติดต่อสื่อสารแบบนี้ว่า Stateless Protocol

จริง ๆ แล้ว Web Browser ก็คือ HTTP client นั่นเอง เหตุผลคือเราใช้ Web Browser เป็นตัวส่ง request ไปที่ Web Server (หรือ HTTP server) เพื่อจะรับ resource ที่ต้องการกลับมาโดยใช้ HTTP protocol.  โดยทั่วไป resource จะกระจายอยู่ตาม network nodes ต่าง ๆ ทั่วโลก ส่ิงหนึ่งที่จะขาดไม่ได้ในการอ้างถึง resource เหล่านี้คือ URL(Universal Resource Locator).  URL คือตัวที่ใช้ชี้ถึงแหล่งที่อยู่ของ resource ว่าอยู่ที่ไหน หลายคนอาจเข้าใจผิดคิดว่า URL ถูกใช้สำหรับ HTTP อย่างเดียวแต่จริง ๆ แล้ว URL สามารถใช้เพื่ออ้างถึง resource อะไรก็ได้ โดยใช้ protocol อะไรก็ได้ ยกตัวอย่างเช่น

http://www.jarticles.com/index.html
เป็น URL ของ HTTP protocol เพื่อใช้โหลดไฟล์ html

http://www.jarticles.com:80/coffee.jpg
เป็น URL ของ HTTP protocol เพื่อใช้โหลดไฟล์ image

http://www.jarticles.com/cgi-bin/sendMail.pl
เป็น URL ของ HTTP protocol เพื่อใช้โหลดค่าที่ได้จากการประมวลผลของ Cgi โปรแกรมชื่อ sendMail.pl

ftp://ftp.jarticles.com/jspTutorial.doc
เป็น URL ของ FTP protocol เพื่อใช้ดาวโหลดไฟล์ document

จากตัวอย่างข้างต้น เราจะเห็นว่าในหนึ่ง URL จะประกอบไปด้วยชื่อของ protocol, ชื่อของ server, port ที่ใช้และ resource ที่ต้องการ ดังรูปแบบข้างล่าง
http://www.jarticles.com:80/index.html
----   ----------------- -------------
 |             |         |    |
Protocol    Hostname    Port Resource

HTTP Structure
จากหลักการทำงานของ HTTP ข้างต้น เราจะเห็นว่าสำหรับการติดต่อสื่อสารระหว่าง Client กับ Server แล้ว ตัว message จะเป็นตัวกลางที่ใช้ในการติดต่อสื่อสารเสมอ และเพื่อให้ง่ายต่อการใช้งานรูปแบบของ message ที่ใช้ใน request หรือ response จึงมีลักษณะคล้าย ๆ กันโดยจะใช้ text เป็นหลักซึ่งโครงสร้างของ message จะประกอบไปด้วย
1. บรรทัดเริ่มต้น (initial line)
2. Header(s)
3. บรรทัดว่าง (a blank line) ซึ่งก็คือ CRLF* หรือการเว้นหนึ่งบรรทัด (วิธีหนึ่งที่ทำได้คือการกด Enter นั่นเอง)
4. message body ซึ่งอาจจะใช้บรรจุไฟล์, คำสั่ง (Query String) หรืออาจจะเป็น output ที่มาจาก server โดยส่วนนี้จะมีหรือไม่มีก็ได้ขึ้นอยู่กับจุดประสงค์ของการใช้งาน
* CRLF = Carriage return (\r) และ Line Feed (\n) ซึ่งก็คือ \u00A และ \u00D ใน ACSII นั่นเอง

รูปแบบโดยทั่วไปของ message จะเป็น

<initial line>
Header1: value1
Header2: value2
Header3: value3
[blank line]
<message body, optional ........................
.............................................................
.............................................................>

ตัวอย่างง่าย ๆ ของ message ที่ Client ใช้อาจจะเป็น
GET /images/coffee.jpg <-- initial line
From: soup@jarticles.com <-- header 
User-Agent: Mozilla/4.72 <-- header 
[blank line] <-- บรรทัดว่าง
หรือ
POST /servlet/searchEngine HTTP/1.0 <-- initial line
From: webmaster@jarticles.com <-- header
User-Agent: Mozilla/4.72 <-- header
[blank line] <-- บรรทัดว่าง
keyword=java&topic=jsp <-- message body

ตัวอย่างง่าย ๆ ของ message ที่ Server ใช้อาจจะเป็น
HTTP 1.0 200 OK <-- initial line
Date: Sunday, 23-July-00 04:01:12 GMT <-- header
Server: Apache/1.3.12(Unix) (Red Hat/Linux) PHP/3.0.15 mod_perl/1.21 <-- header
MIME-version: 1.0 <-- header
Content-type: text/html <-- header
Content-length: 115 <-- header
[blank line] <-- บรรทัดว่าง
<HTML><HEAD><TITLE>HTTTP Tutorial</TITLE></HEAD> <-- message body
<BODY>This is a tutorial, but please visit me again...</BODY> <-- message body (cont.)
<HTML> <-- message body (cont.)

Initial Request Line
initial line ของ request จะแตกต่างจาก initial line ของ response เล็กน้อยโดย  initial line ของ request จะมีสามส่วนคือ
1. ชื่อของ method เช่น GET, POST, HEAD, TRACE
2. local path ของ resource ที่ client ต้องการ
3. เวอร์ชั่นของ HTTP/x.x ที่ HTTP Client ใช้
สามส่วนนี้จะประกอบกันเป็น initial line โดยแต่ละส่วนจะถูกแยกออกจากกันโดยใช้ช่องว่าง (space) ดังตัวอย่างข้างล่าง

GET /path/to/file/index.html HTTP/1.0
ตัวอย่างนี้ใช้ method ที่ชื่อ GET เพื่อขอ resource (ในที่นี้คือไฟล์) ชื่อ /path/to/file/index.html โดยใช้ HTTP/1.0 protocol

ทำไมถึงต้องใช้ local path
ก่อนที่ HTTP Client จะส่ง request ไปที่ HTTP Server, HTTP Client จะสร้างคอนเนคชั่นขึ้นมาอันหนึ่งก่อนโดยใช้ socket. การสร้าง socket จะต้องทำการกำหนดชื่อของ host ที่จะติดต่อ ยกตัวอย่างเช่น ถ้า url เป็น http://www.jarticles.com/path/to/file/index.html, ชื่อของ host ก็จะเป็น www.jarticles.com ดังนั้นการกำหนดเพียง local path* เพื่อบ่งบอกถึง resource ที่ต้องการในส่วนของ initial request line ซึ่งก็คือ /path/to/file/index.html ก็เพียงพอแล้ว
* API ที่ใช้ใน Server side application มักอ้างถึงส่วนที่เป็น local path นี้ว่า requested URI (ตัว I มาจาก Identifier)
Note:
1) ชื่อของ method จะต้องใช้ตัวใหญ่เสมอ
2) เวอร์ชั่นของ HTTP จะอยู่ในรูป HTTP/x.x และจะต้องเป็นตัวใหญ่เสมอ

Initial Response Line
โดยทั่วไป initial response line มักจะเรียกว่า status line ซึ่งประกอบไปด้วยสามส่วนย่อย คือ
1. เวอร์ชั่นของ HTTP/x.x ที่ server ใช้สำหรับส่ง message 
2. response status code ซึ่งเป็นตัวบอกว่าผลของ request ที่ Client ส่งมาเป็นอย่างไร
3. reason phase เป็นตัวอธิบายความหมายของ response status code อีกทีหนึ่ง

ยกตัวอย่างเช่น
HTTP/1.0 200 OK
หรือ
HTTP/1.0 404 Not Found

Note: 
1) เวอร์ชั่นของ HTTP จะต้องอยู่ในรูปของ HTTP/x.x และจะต้องเป็นตัวใหญ่เสมอ
2) response status code เป็น code ที่ส่งมาให้ Computer (Client) อ่านซึ่งจะมี reason phase เป็นตัวอธิบายให้มนุษย์ (Human Being) อ่านอีกทีหนึ่ง
3) response status code จะอยู่ในลักษณะของเลขสามหลัก โดยหลักแรกจะบอกถึงความหมายโดยทั่ว ๆ ไปของ response

  • 1xx เป็น code ที่ใช้บอกถึงเหตุการณ์ต่าง ๆ ที่เกิดขึ้นในการสื่อสารระหว่าง Client และ Server
  • 2xx เป็น code ที่บ่งบอกว่า request ที่ส่งจาก Client ถูกทำให้ complete แล้ว
  • 3xx เป็น code ที่บอกให้ Client ทำการ redirect ไปที่ url อื่นแทน 
  • 4xx เป็น code ที่บ่งบอกถึงความผิดพลาดที่เกิดขึ้นจากส่วนของ Client
  • 5xx เป็น code ที่บ่งบอกถึงความผิดพลาดที่เกิดขึ้นจากส่วนของ Server
status code ที่พบเห็นโดยทั่วไป คือ
100 Continue 
เซฟเวอร์ได้รับ request บางส่วนจาก Client แล้ว, Client กรุณาส่งส่วนที่เหลือมาให้ด้วย
200 OK 
request ที่มาจาก Client ถูกต้องและ resource ที่ client ต้องการอยู่ใน message body ของ response นี้แล้ว
301 Moved Permanently
resource ที่ Client ต้องการเคยอยู่ที่ Server นี้แต่ถูกย้ายไปอยู่ที่อื่นแล้ว
302 Moved Temporarily
resource ที่ Client ต้องการถูกย้ายไปอยู่ที่ Server อื่นหรือไม่สามารถ access ได้ชั่วคราว
400 Bad Request
server ไม่สามารถเข้าใจ request ที่ Client ส่งมา
403 Forbidden
server เข้าใจ request ที่ Client ส่งมาแต่ไม่ต้องการที่จะส่ง resource ที่ Client ต้องการกลับไปให้ : )
404 Not Found
server ไม่มี resource ที่ Client ต้องการ
500 Server Error
เกิดข้อผิดพลาดขึ้นในส่วนของ Server (โดยทั่่วไป Error นี้จะเกิดขึ้นในกรณีที่ request ส่งมาเรียก Server Side Application ที่รันบน Server นี้แต่เกิดข้อผิดพลาดขึ้นระหว่างการประมวลผลซึ่งโดยทั่วไปจะเกิดขึ้นเพราะโปรแกรมมีบัค)

Header(s)
โดยทั่วไป header จะเป็นส่วนที่บอกถึงรายละเอียดของ request (ที่กำลังส่งไปให้ Server) หรือ response (ที่กำลังส่งกลับมายัง Client) ยกตัวอย่างเช่น 
- Client จะส่ง Header ที่บอกถึงชนิดและขนาดของข้อมูลที่อยู่ข้างใน message body ในกรณีที่ Client ต้องการ upload ไฟล์ไปยัง server
- Server อาจจะส่ง Header ที่เกี่ยวกับชนิดและขนาดของ resource ที่ Client กำลังจะได้รับโดยใช้ Content-Type และ Content-Length
header จะเป็นลักษณะของ text format โดยในหนึ่งบรรทัดจะถูกใช้สำหรับหนึ่ง header ซึ่งจะอยู่ในรูปของ "Header-Name: value" และจบด้วย CRLF ยกตัวอย่างเช่น

From: soup@jarticles.com
User-Agent: Mozilla/4.72
Content-Type: text/html
Content-Length: 250

Note: 
1) ชื่อของ header สามารถใช้ตัวใหญ่หรือตัวเล็กก็ได้
2) เราสามารถเว้นช่องว่างหรือ tab ระหว่าง ":" ของ Header-Name และ value กว้างเท่าไหร่ก็ได้
3) ใน HTTP1.0 จะมี header กำหนดไว้ 16 แบบแต่ของ HTTP1.1 จะมีถึง 46 แบบด้วยกัน

header ที่มักพบเห็นทั่วไปในส่วนของ Client 
From: 
เป็น header ที่ใช้สำหรับเก็บ email address ของผู้ที่กำลังส่ง request ยกตัวอย่างเช่น From: soup@jarticles.com
User-Agent: 
เป็น header ที่ใช้บ่งบอกถึงชื่อของโปรแกรมที่ใช้เป็น HTTP Client ยกตัวอย่างเช่น User-Agent: Mozilla/4.72

header ที่มักพบเห็นทั่วไปในส่วนของ Server
Server: 
เป็น header ที่จะคล้ายกับ User-Agent แต่เป็นตัวบอกถึงชื่อของโปรแกรมที่ใช้เป็น HTTP Server ยกตัวอย่างเช่น Server: Apache/1.93
Last-Modified: 
เป็น header ที่ใช้บอกถึงเวลาครั้งสุดท้ายที่ resource ที่ client ต้องการถูกเปลี่ยนแปลง (modify/update) โดยเวลาที่ใช้จะเทียบจาก GMT (Greenwich Mean Time) ยกตัวอย่างเช่น เวลาของเมืองไทยถือว่าเป็น GMT+7.00 ถ้าตอนนี้เวลาในเมืองไทยคือ Sun, 23 July 2000 20:39:56 เวลาที่เป็น GMT ก็คือ 
Last-Modified: Sun, 23 July 2000 13:39:56 GMT

Message Body
เมื่อไรก็ตามที่ client หรือ server ต้องการส่งเดต้าไปกับ message, ส่วนที่เป็น message body จะเป็นส่วนที่ใช้สำหรับเก็บเดต้าดังกล่าว
ในกรณีของ client ตัว message body อาจใช้สำหรับบรรจุไฟล์ที่ต้องการ upload หรือใช้สำหรับเก็บเดต้าที่มาจาก element ต่าง ๆ ของ HTML form  แล้วส่งไปยัง server ก็ได้ 
ในกรณีของ server ตัว message body จะเป็นส่วนที่ใช้เก็บ resource ที่ client ทวงถามหรืออาจใช้สำหรับเก็บคำอธิบาย ต่าง  ๆ ในกรณีที่มี error เกิดขึ้นก็ได้
ถ้า message มีส่วนของ message body, client หรือ server มักจะเพิ่ม header ที่ช่วยบอกถึงรายละเอียดของ message body ดังกล่าวด้วย ยกตัวอย่างเช่นถ้า server ต้องการส่ง resource ที่เป็นไฟล์ image มาให้ client, header ที่ถูกเพิ่มขึ้นมาก็จะเป็น
Content-Type: image/gif เป็น header ที่บ่งบอกถึง MIME type ของ data ที่อยู่ใน message body
Content-Length: 1026 เป็น header ที่บ่งบอกถึงขนาดของ message body ในหน่วย byte

ตัวอย่างของการส่ง message ระหว่าง client และ server
เกิดอะไรขึ้นบ้าง ถ้าสมมุติว่าเราต้องการ resource จาก URL ข้างล่างนี้
http://www.jarticles.com/tutorials/basic/helloworld.html
(Client = Web Browser, Server = Web Server)

ขั้นแรก Client จะทำการเรียกใช้ socket เพื่อคอนเนคไปที่เซฟเวอร์่ชื่อ www.jarticles.com ซึ่งโดยปกติจะติดต่อไปที่ port 80 ซึ่งเป็น default port ของ HTTP protocol (ในกรณีที่ต้องการคอนเนคไปที่ port อื่นก็สามารถทำได้โดยการเพิ่มส่วนของ port เข้าไปหลังจากส่วนของ hostname เช่น http://www.jarticles.com:8080/tutorials/advance/hellocorba.html, Client จะคอนเนคไปที่ port 8080 แทน)

หลังจากนั้น Client จะทำการส่ง request message
GET /tutorials/basic/helloworld.html HTTP/1.0
From: soup@jarticles.com
User-Agent: Mozilla/4.72
[blank line]

หลังจากที่ Server ได้รับ message ข้างบนแล้ว, Server จะส่ง response พร้อมทั้ง resource ที่ Client ต้องการกลับมาดังนี้
HTTP/1.0 200 OK
Date: Sunday, 23-July-00 04:01:12 GMT
Content-type: text/html
Content-length: 1556
[blank line]
<HTML><HEAD><TITLE>HTTTP Tutorial</TITLE></HEAD>
<BODY>This is HelloWorld tutorial, but please read it for fun : )
(more file contents)
...
...
...
</BODY>
<HTML>

ท้ายสุด Server จะทำการปิดคอนเนคชั่นของ Client

ทดสอบด้วยตนเอง
ในกรณีที่ผู้อ่านอยากทดสอบการส่ง message ระหว่าง Client และ Server ด้วยตัวเองก็สามารถทำได้โดยการ telnet (แทนส่วนของ Client) คอนเนคไปยัง Server ที่ใดที่หนึ่งซึ่งกำลังรัน HTTP Server อยู่ ยกตัวอย่างเช่น
telnet www.jarticles.com 80 (คอนเนคไปที่ Server ชื่อ www.jarticles.com ที่ port 80)

หลังจากนั้นให้ทำการพิมพ์ initial line และ header ต่าง ๆ เข้าไปเอง ยกตัวอย่างเช่น
GET /index.html HTTP/1.0
[blank line] ซึ่งเราใช้ enter แทน
enter

ผลที่ได้ก็จะเป็นอย่างตัวอย่างข้างล่างนี้
telnet www.jarticles.com 80
Trying 207.155.252.7...
Connected to www.jarticles.com.
Escape character is '^]'.
GET /index.html HTTP/1.0

HTTP/1.0 200 Document follows
Date: Mon, 24 Jul 2000 03:07:57 GMT
Server: ConcentricHost-Ashurbanipal/1.7 (ConcentricHost)
Content-type: text/html

<HTML>
<HEAD>
<TITLE>
ConcentricHost</TITLE>
</HEAD>
...
...
...
</HTML>

The GET Method
ถ้าใครเคยใช้ search Engine ในการหาข้อมูลบางอย่างอาจจะสังเกตเห็นว่าหลังจากที่ใส่ keyword ลงไปแล้วคลิกปุ่ม search, URL ที่อยู่ตรง Location Toolbar (Netscape), Address Bar (IE) ของ Web Browser  จะเปลี่ยนเป็นอะไรคล้าย ๆ อย่างนี้

http://www.google.com/search.cgi?keyword=jarticles
(search ที่ www.google.com โดยใช้ keyword = "jarticles")

ถ้าลองดูส่วนที่อยู่หลังจากส่วนของ hostname (www.google.com) แล้วเราจะเห็นว่า requested URI (/search.cgi?keyword=jarticles) ที่เห็นไม่ได้เป็น html ไฟล์อย่างทั่ว ๆ ไป แต่กลับกลายเป็นชื่อของโปรแกรม(search.cgi), เครื่องหมายคำถาม(?)และ keyword ที่เราใช้ค้นหาแทน

อย่างที่กล่าวมาแล้วในส่วนต้นของบทความว่า resoruce จริง ๆ แล้วก็คือตัวที่ใช้บ่งชี้ถึงเดต้าที่อยู่ที่ server.  resource อาจเป็นไฟล์หรืออาจเป็น query string ที่ใช้ส่งไปเรียกโปรแกรมที่อยู่ที่ server ก็ได้ ซึ่งในกรณีของตัวอย่าง search Engine ข้างต้นตัว resource ก็คือโปรแกรมที่ชื่อ search.cgi นั่นเอง
โดยทั่วไป response ที่ได้กลับมาจาก server อาจจะอยู่ในรูปของไฟล์ถ้า resource ที่เราทวงถามเป็นไฟล์ ยกตัวอย่างเช่น http://www.jarticles.com/tutorial/http.html หรืออาจจะเป็น output ที่ได้จากการประมวลผลของประแกรมที่เราผ่าน query string เข้าไป เช่นถ้าเราส่ง query string ไปที่ search engine ผลที่เราจะได้กลับมาก็คือ link ต่าง ๆ ที่เกี่ยวข้องกับ keyword ที่เราใช้้ค้นหานั่นเอง

โดยทั่วไป Web Browser (Client) จะใช้ GET Method ในการส่ง request message ไปที่ server ในกรณีที่ resource ที่ต้องการเป็นไฟล์ อย่างไรก็ตาม GET ยังสามารถใช้ในการส่ง query string สั้น ๆ ไปยังโปรแกรมที่รันอยู่ที่ server ได้อีกด้วย ยกตัวอย่างเช่น
ถ้าเราต้องการส่งเดต้าชื่อ keyword โดยมีค่าเท่ากับ jarticles ไปที่ server ชื่อ www.google.com โดยเจาะจงไปที่ resource ซึ่งเป็น cgi โปรแกรมชื่อ search.cgi วิธีการทำก็คือ
1. กำหนด resource ลงไปในส่วนของ request URI ซึ่งจะอยู่หลังจากส่วนของ hostname ซึ่งจะได้ http://www.google.com/search.cgi
2. ใส่ตัวเครื่องหมายคำถามเพื่อบอก server ว่าส่วนที่เหลือถัดไปจะเป็นส่วนของเดต้าซึ่งจะได้ http://www.google.com/search.cgi?
3. ทำการ encode โดยวิธีการที่เรียกว่า URL-encoding ไปที่ชื่อและค่าของตัวแปรต่าง ๆ ซึ่งในกรณีของเราตัวแปรก็คือ keyword ซึ่งจะได้
http://www.google.com/search.cgi?keyword=jarticles

ถ้าเราพิมพ์ URL ข้างบนเข้าไปใน Web Browser แล้วกดปุ่ม Enter, ตัว Web Browser จะทำตีความ URL ดังกล่าวซึ่งผลที่ได้คือการใช้ GET ส่ง request message ไปที่ server ที่ชื่อ www.google.com โดยจะแนบ "jarticles" keyword ไปกับ request ซึ่ง initial line ของ request message จะเป็นอะไรคล้าย ๆ ข้างล่างนี้
GET /search.cgi?keyword=jarticles HTTP/1.0
From: soup@jarticles.com
User-Agent: Mozilla/4.72
[blank line]

หลังจากนั้นเราจะได้ลิงค์ต่าง ๆ ที่เกี่ยวกับ jarticles กลับมา 
Note: URL จริง ๆ ที่ใช้กับ www.google.com จะต่างจาก URL ข้างบนเล็กน้อย
วิธีการส่ง query string ไปกับ URL เหมาะสำหรับ query string ที่ไม่ยาวมากนัก โดยทั่วไปความยาวของ URL มักจะจำกัดอยู่ที่ 80 characters ซึ่งโดยทั่ว ๆ ไปแล้ว character ที่ถัดจากนั้นจะถูกตัดออกไปโดยอัตโนมัติ (จะตัดหรือไม่ตัวจริง ๆ ขึ้นอยู่กับการ implement ของ server แต่ละตัว)

URL-Encoding
ในการส่งเดต้าไปที่ server โดยวิธีการ GET หรือวิธีการ POST (จะพูดถึงถัดไป) นั้นชื่อและค่าของตัวแปรต่าง ๆ ซึ่งอยู่หลังจากเครื่องหมายคำถามในกรณีของ GET หรืออยู่ในส่วนของ message body ในกรณีของ POST จะต้องถูกผ่านการ encode โดยวิธีการที่เรียกว่า URL-Encoding เสียก่อน
ทำไมต้อง encode?
โดยทั่วไปตัว URL เองจะมี character บางตัวที่ใช้สำหรับความหมายพิเศษ เช่น  :, /, ~ & ? ซึ่งในบางครั้งชื่อและค่าของตัวแปรต่าง ๆ ที่ถูกส่งไปที่ server อาจจะมี character เหล่านี้ปะปนอยู่ด้วย เพื่อหลีกเลี่ยงความสับสนในการตีความของ server, character ต่าง ๆ ที่เป็น character ที่ใช้ใน URL จะต้องถูก encode เสียก่อน โดยมีหลักการดังต่อไปนี้
1. ให้ทำการเปลี่ยน unsafe characters ต่าง ๆ ที่อยู่ในชื่อและค่าของตัวแปรให้กลายเป็น "%xx" โดย "xx" คือค่าของ ascii ของ character นั้น ๆ ในแบบ hexadecimal ซึ่ง unsafe characters เหล่านี้รวมไปถึง = , &, %, +, และ characters ต่าง ๆ ที่ไม่สามารถพิมพ์ได้หรือแม้กระทั่ง characters ที่เราต้องการจะ encode เอง
2. ให้ทำการเปลี่ยนช่องว่าง (space) ทั้งหมดให้กลายเป็นเครื่องหมายบวก (+)
3. จับคู่ชื่อและค่าของตัวแปรต่าง ๆ ด้วย =
4. ถ้ามีชื่อและค่าของตัวแปรมากกว่าหนึ่งตัว ให้นำชื่อและค่าของตัวแปรแต่ละคู่มาเชื่อมติดกันด้วยเครื่องหมาย &
5. นำชื่อและค่าของตัวแปรที่เชื่อมติดกันทั้งหมดไปใส่ที่ URL โดยมีเครื่องหมาย ? อยู่ข้างหน้า(ในกรณีของ GET) หรือนำไปใส่ที่ message body (ในกรณีของ POST) ยกตัวอย่างเช่น ถ้าเรามีชื่อและค่า

(name, value) = ("keyword", "jarticles") 
(name, value) = ("name", "Soup & friends")
หลังจากทำการ encode เราจะได้ String ออกมาเป็น keyword=jarticles&name=Soup+%26+friends โดย String นี้มีความยาวเท่ากับ 39
Note: & = %26 in hex

The POST Method
บางครั้งเราอาจจะไม่ต้องการส่งเดต้าไปยัง server ด้วยการติดเดต้าเหล่านั้นไปกับ URL ด้วยเหตุผลที่ว่าเดต้าเหล่านั้นอาจเกี่ยวข้องกับข้อมูลส่วนตัวของเรา ยกตัวอย่างเช่น login และ password ที่ใช้เป็นตัวผ่านเข้าไปในเวปไซด์ต่าง ๆ ซึ่งในกรณีที่เราใช้ GET, URL หลังจากที่เราทำการ login ไปแล้ว URL ที่อยู่ตรง Address Bar อาจจะออกมาเป็น

http://www.myserver.com/login.cgi?login=me&password=youandme

ถ้าบังเอิญว่าระหว่างที่เราล๊อกอิน มีคนอื่นนั่งอยู่ข้าง ๆ ด้วยพอดี คนคนนั้นก็อาจจะตาดีและนำเอาข้อมูลของเราไปใช้อย่างผิด ๆ ได้
อีกกรณีหนึ่งคือ กรณีของเดต้าที่เราติดไปกับส่วนของ request URI ทำให้ URL มีความยาวมากกว่าความยาวของ URL ที่ server กำหนดไว้ ผลกระทบที่อาจเกิดขึ้นคือเดต้าบางส่วนของเราอาจหายไปเนื่องจากการตัดทอนโดย server

วิธีการที่เราสามารถใช้เพื่อปิดบังข้อมูล(แบบง่าย ๆ) หรือเพื่อส่งเดต้าที่มีความยาวมาก ๆ ก็คือการใช้ POST method
POST ต่างกับ GET ตรงที่ว่า POST จะไม่ทำการติดเดต้าไปกับ URL แต่ POST จะทำการใส่เดต้าเข้าไปในส่วนของ message body ของ request message แทนซึ่งในกรณีนี้ request URI จะมีปรากฎเพียงชื่อของโปรแกรมที่เราต้องการส่งเดต้าไปให้เท่านั้น
ในการส่งเดต้าไปในส่วนของ message body, เพื่อให้ง่ายต่อการตีความโดย server ทาง POST method จึงมีการบังคับให้ใส่ header พิเศษเพื่อบรรยายรายละเอียดต่าง ๆ ของเดต้าที่อยู่ใน message body นั้นอีกด้วยซึ่งโดยทั่วไป header ที่มักจะถูกเพิ่มเข้าไปก็คือ Content-Type และ Content-Length header

การใช้ POST ที่มักพบเห็นโดยทั่วไปคือการใช้ POST ในการส่งเดต้าที่มาจาก HTML Form ยกตัวอย่างเช่น

<FORM METHOD="POST" NAME="loginform" ACTION="http://www.jarticles.com/cgi-bin/login.cgi">
<INPUT TYPE="text" NAME="userName" SIZE="20" MAXLENGTH="20" VALUE="">
<INPUT TYPE="PASSWORD" NAME="password" SIZE="20" MAXLENGTH="20" VALUE="">
<INPUT TYPE="SUBMIT" VALUE="Go!">
</FORM>

ซึ่งก็คือ

Login:
Password:
 

หลังจากที่เราทำการคลิกที่ปุ่ม GO! แล้ว Web Browser จะทำการส่ง message ไปที่ server ซึ่งคล้ายกับ message ข้างล่างนี้
POST /cgi-bin/login.cgi HTTP/1.0
From: soup@jarticles.com
User-Agent: Mozilla/4.72
Content-Type: application/x-www-form-urlencoded
Content-Length: 32

userName=bababa&password=wow

Note:  ในกรณีของการส่งเดต้าจาก HTML Form, Client จะทำการเซ็ต Content-Type เป็น application/x-www-form-urlencoded และ Content-Length จะมีค่าเท่ากับความยาวของชื่อและค่าของ form elements ต่าง ๆ ที่อยู่ใน HTML Form รวมกันซึ่งจากตัวอย่างของเราก็คือ form element ที่ชื่อ userName และ password

นอกจากนี้ POST ยังสามารถใช้กับการส่งเดต้าแบบอื่น ๆ ได้อีก โดย format จะขึ้นอยู่กับวิธีการส่งที่ทาง Web Browser และ Web Server ได้ทำการตกลงกันไว้ ยกตัวอย่างเช่น ในกรณีของไฟล์ Upload ตัว Content-Type ก็จะถูกเซ็ตเป็น Multipart/form-date แทน ซึ่งตัวอย่างของ HTML Form อยู่ข้างล่างนี้

<FORM ACTION="/upload/uploadServlet" EncType="multipart/form-data" METHOD="POST">
Which file do you want to upload? <INPUT TYPE="file" NAME="yourfile"><br>
<INPUT TYPE="submit">
</FORM>


Copyright (C) 2000 www.jarticles.com.