Query String trong URL khi người dùng truy cập vào trang chính của en.wikipedia.org
Trên mạng lưới World Wide Web, một **chuỗi truy vấn** (tiếng Anh: *query string*) là một phần của một URL chứa dữ liệu không phù hợp trong cấu trúc đường dẫn. Query string thường gồm những trường được thêm vào một URL bởi một trình duyệt web hoặc bởi một ứng dụng client khác (ở đây nói đến mô hình client-server với web browser là một client), ví dụ như là một form HTML.

Một web server có thể xử lý một yêu cầu HTTP (HTTP request) bằng cách đọc một file từ hệ thống file của server dựa trên URL hoặc bằng cách xử lý các yêu cầu dựa trên logic đối với các tài nguyên cụ thể. Trong trường hợp các logic đặc biệt được sử dụng, query string sẽ được sử dụng cho quá trình xử lí logic đó, cùng với thành phần đường dẫn của URL.

Cấu trúc
--------

Một URL điển hình chứa một query string sẽ có dạng như sau:

> `http://example.com/over/there?name=ferret`
> 
> 
> 

Khi một máy chủ nhận một yêu cầu một trang như vậy, nó có thể trả về trang người dùng yêu cầu, và bỏ qua các query string mà trong trường hợp này là, `name=ferret`.  Dấu hỏi trong cấu trúc trên được dùng để phân chia các thành phần scheme, host, port (nếu có) và path với query string và không phải là thành phần của query string.

Các web frameworks có thể cung cấp các phương pháp để xử lí cú pháp (parse) nhiều thông số trong các query string, khi chúng được tách ra trong các URL bởi các dấu phân cách. Trong URL ví dụ dưới đây, các query string được tách ra bởi kí hiệu '&':

> `http://example.com/path/to/page?name=ferret&color=purple`
> 
> 
> 

Ở ví dụ này, có thể thấy rằng có 2 query string trong URL, đó là `name=ferret` và `color=purple`.

Các query string không có cấu trúc tiêu chuẩn. Các phương pháp được sử dụng để phân tích cú pháp các query string có thể khác nhau, tùy thuộc vào các nhà phát triển của website đó.

Một liên kết trong một trang web có thể có một URL mà có một query string. HTML xác định ba cách mà một người có thể tạo ra những query string:

* Một HTML form thông qua các thẻ `<form>...</form>`
* Một ánh xạ từ phía server thông qua `ismap` là một thuộc tính của thẻ `<img>` với cấu trúc `<img ismap>`
* Một thẻ tìm kiếm giờ đây đã bị bác bỏ là `<isindex>`

### Web forms

Khi một web form chứa các trường `field1`, `field2`, `field3`  được gọi, các nội dung của các trường đó sẽ được mã hóa thành một query string như sau:

> `field1=value1&field2=value2&field3=value3...`
> 
> 
> 

* Các query string bao gồm một loạt các cặp trường giá trị.
* Trong mỗi cặp, tên trường và giá trị được tách ra bởi một dấu bằng, '`=`'.
* Một loạt các cặp được cách nhau bằng kí hiệu '&' (hoặc dấu chấm phẩy, '`;`' cho đường dẫn được nhúng trong HTML và không được tạo ra bởi một cặp thẻ `<form>...</form>`).

Dù các query string không có cấu trúc tiêu chuẩn, các web frameworks cho phép nhiều giá trị được kết hợp trong một trường (ví dụ như `field1=value1`và `field1=value2`và `field2=value3`).

Với mỗi trường của một form, query string có một cặp `field=value`. Các web form có thể bao gồm những trường mà người dùng không thể nhìn thấy, các trường này được lồng trong các query string khi các form được gởi (submit).

W3C khuyến cáo tất cả các web server hỗ trợ dùng dấu chấm phẩy bên cạnh dấu "&" để cho phép các `application/x-en-form-urlencoded` query string trong URL trong tài liệu HTML mà không cần phải phân cách dấu "&".

Các nội dung form chỉ được mã hóa trong các URL's query string trong phương thức đệ trình của form là GET. Phương pháp mã hóa tương tự được dùng mặc định khi phương thức đệ trình là POST, nhưng kết quả được server hiểu như là một yêu cầu HTTP (HTTP request) chứ không phải là một URL bị thay đổi.

### Query string trong công cụ tìm kiếm

Lấy ví dụ với công cụ tìm kiếm Google và trình duyệt Google Chrome. Khi người dùng truy xuất vào thanh tìm kiếm của trình duyệt và gõ nội dung tìm kiếm vào đó, nội dung tìm kiếm sẽ được gởi đến server ở dạng query string cùng với phương thức GET và thêm nào nhiều quy trình mã hóa khác, tất cả tạo nên URL mà người dùng có thề nhìn thấy trên thanh tìm kiếm. Do đó việc này sẽ rất tiện lợi khi người dùng chỉ cần nhập vào công cụ tìm kiếm nội dung cần tìm thì có thể sẽ nhận được nội dung yêu cầu.

Khi đoạn văn bản trên thanh tìm kiếm được gởi đi (người dùng nhấn Enter), nó sẽ được mã hóa thành một query string có dạng như sau:

> `argument1+argument2+argument3...`
> 
> 
> 

Các query string bao gồm một loạt các đối số được xử lí cú pháp với các khoảng trắng được thay bằng dấu cộng '+'.

Mã hóa URL
----------

Một số ký tự không thể là thành phần của một URL (ví dụ như khoảng trắng) và một số ký tự khác có một ý nghĩa đặc biệt trong một URL: ví dụ, ký tự `#` có thể được dùng để tiếp tục xác định một phần phụ (hoặc mảnh) của một tài liệu. Trong form HTML, ký tự `=` được sử dụng để tách một tên từ một giá trị. Cú pháp URI chung sử dụng mã hóa URL để giải quyết với vấn đề này, trong khi các HTML form tạo thêm các giải pháp thay thế chứ thay vì áp dụng việc mã hóa bằng ký tự "%" cho tất cả các ký tự. Ký tự khoảng trắng được mã hóa bằng '+' hoặc "`%20`".

HTML 5 xác định những thay đổi sau khi một form HTML được gởi tới trình lên server bằng giao thức GET:

* Một ký tự nếu không có ký tự mã hóa tương ứng thì sẽ được thay thế bởi danh sách Tham chiếu ký tự số tương ứng của HTML
* Khoảng trắng được mã hóa bằng kí tự '+' hoặc '`%20`'
* Các kí tự (`A`–`Z` và `a`–`z`), số (`0`–`9`) và các ký tự '`*`','`-`','`.`' và '`_`' đều được giữ nguyên, không mã hóa
* Tất cả các ký tự khác được mã hóa bằng `%HH` hex đại diện với bất kỳ ký tự không phải ASCII nào khác đều được mã hóa bằng UTF-8 (hoặc các mã hóa quy định khác)

Ví dụ
-----

Nếu một form được nhúng trong một trang HTML như sau:

```
<form action="cgi-bin/test.cgi" method="get">
  <input type="text" name="first" />
  <input type="text" name="second" />
  <input type="submit" />
</form>

```
và người dùng chèn vào chuỗi "this is a field" và "was it clear (already)?" trong cả hai thuộc tính <input> first và second và nhấn nút gửi, chương trình test.cgi sẽ có query string như sau

`first=this+is+a+field&second=was+it+clear%28already%29%3F`.

Nếu các form được xử lý trên server bởi một CGI script, các script có thể sẽ thường nhận query string như là một biến môi trường tên là `QUERY_STRING`.

Theo dõi
--------

Một chương trình nhận được một query string có thể bỏ qua một phần hoặc tất cả. Nếu các URL yêu cầu tương ứng với một tập tin và không phải là một chương trình, cả query string sẽ bị bỏ qua. Tuy nhiên, dù các query string có được sử dụng hay không, toàn bộ URL có query string đều được lưu trữ trong các log files của server.

Việc lưu lại này cho phép theo dõi người dùng, tương tự như cách cung cấp HTTP cookies. Để làm việc này, mỗi khi người dùng tải một trang, một địa chỉ duy nhất phải được chọn và thêm vào tất cả URL của trang như một query string. Ngay sau khi các người dùng dử dụng các đường dẫn này, những URL tương ứng được sẽ được gởi yêu cầu tới server. Với cách này, việc tải một trang sẽ liên kết với trang trước đó.

Ví dụ, khi một trang web có đoạn chương trình HTML sau được yêu cầu:

```
 <a href="foo.html">Wikipedia</a>
 <a href="bar.html">Query String</a>

```
một chuỗi duy nhất, như `e0a72cb2a2c7` được chọn, và đoạn mã HTML sẽ bị thay đổi như sau:

```
 <a href="foo.html?e0a72cb2a2c7">Wikipedia</a>
 <a href="bar.html?e0a72cb2a2c7">Query String</a>

```
VIệc thêm vào query string không thay đổi cách mà trang web hiển thị với người dùng. Ví dụ, khi người dùng truy cập vào liên kết đầu tiên trong trang HTML ở trên, trình duyệt yêu cầu trang `foo.html?e0a72cb2a2c7` tới server, và server sẽ bỏ qua những gì sau dấu `?` và trả về cho browser trang `foo.html` như mong đợi, và thêm vào các query string đến liên kết của nó.

Sự khác biệt giữa query string dùng cho việc theo dõi người dùng với HTTP cookies là:

1. Query string là một phần của URL, và do đó nếu người dùng copy cả URL và gởi cho người dùng khác thì người dùng khác sẽ nhận được URL gồm query string; cookie có thể được lưu trên trình duyệt, nhưng không được lưu hoặc gửi kèm theo URL.
2. Nếu người dùng truy cập vào cùng một web server bởi 2 đường dẫn riêng biệt (hoặc nhiều hơn), thì server sẽ trả về 2 query string khác nhau, trong khi các cookie lưu trữ đều giống nhau.
3. Người dùng có thể vô hiệu hóa cookie, trong trường hợp đó, cookies sẽ không thể dùng để theo dõi người dùng được. Tuy nhiên, query string có thể sử dụng để theo dõi người dùng trong mọi tình huống.

Vấn đề tương thích
------------------

Theo đặc tính kĩ thuật của HTTP:

> Trên thực tế, có nhiều giới hạn đặc biệt khác nhau về độ dài của một HTTP request. Khuyến cáo rằng tất cả phía gởi và phía nhận HTTP request đều hỗ trợ độ dài request tối thiểu là 8000 octet.
> 
> 

Nếu một URL quá dài, phía web server sẽ bị lỗi với HTTP status code 414 Request-URI Too Long. Một phương pháp phổ biến để giải quyết vấn đề này là sữ dụng POST request thay vì GET request, và lưu các giá trị trong phần request body. Kích thước giới hạn của request body sẽ lớn hơn kích thước độ dài của URL, theo tiêu chuẩn. Ví dụ, kích thước của một POST request, mặc định là 2 MB trên IIS 4.0 và 128 KB trên IIS 5.0. Giới hạn này có thể cấu hình được trên Apache2 sử dụng `LimitRequestBody` directive, việc cấu hình này quy định được kích thước của request body (số byte) từ 0 đến 2147483647 (2 GB).

Xem thêm
--------

* HTTP cookie
* Giao thức HTTP
* URL
* URI

Tham khảo
---------

1. ↑  T. Berners-Lee, W3C/MIT, R. Fielding, Day Software, L. Masinter, Adobe Systems (tháng 1 năm 2005). "RFC 3986". "Syntax Components" (section 3).Quản lý CS1: nhiều tên: danh sách tác giả (liên kết)
2. ↑  T. Berners-Lee, W3C/MIT, R. Fielding, Day Software, L. Masinter, Adobe Systems (tháng 1 năm 2005). "RFC 3986". "Query" (section 3.4).Quản lý CS1: nhiều tên: danh sách tác giả (liên kết)
3. ↑  ServletRequest (Java EE 6). Docs.oracle.com (2011-02-10). Truy cập 2013-09-08.
4. ↑  uri – Authoritative position of duplicate HTTP GET query keys. Stack Overflow (2013-06-09). Truy cập 2013-09-08.
5. ↑  Forms in HTML documents. W3.org. Truy cập 2013-09-08.
6. ↑  Performance, Implementation, and Design Notes. W3.org. Truy cập 2013-09-08.
7. ↑  "<isindex>". *HTML (HyperText Markup Language)*. Bản gốc lưu trữ ngày 19 tháng 10 năm 2017. Truy cập ngày 2 tháng 12 năm 2017.
8. ↑  "HTML/Elements/isindex". *W3C Wiki*. Bản gốc lưu trữ ngày 3 tháng 12 năm 2017. Truy cập ngày 2 tháng 12 năm 2017.
9. ↑  "HTTP/1.1 Message Syntax and Routing". *ietf.org*. Truy cập ngày 5 tháng 8 năm 2021, "3.1.1. Request Line"Quản lý CS1: postscript (liên kết)
10. ↑  "core – Apache HTTP Server, LimitRequestBody Directive". Truy cập ngày 5 tháng 8 năm 2021, "LimitRequestBody Directive"Quản lý CS1: postscript (liên kết)

Liên kết ngoài
--------------

* RFC 986