2012-06-10 24 views
9

Đầu tuần này, tôi đã phải làm một cái gì đó mà cảm thấy giống như một vi phạm ngữ nghĩa. Hãy để tôi giải thích.HTTP GET và POST ngữ nghĩa và hạn chế

Tôi đã tạo một ứng dụng khách AJAX đơn giản, đó là yêu cầu một dịch vụ với một số tham số nhất định. Vì toàn bộ ứng dụng về cơ bản là chỉ đọc, tôi nghĩ rằng việc sử dụng HTTP GET là cách để đi. Một số thông số mà tôi phải chuyển là đơn giản (chẳng hạn như thứ tự sắp xếp hoặc số trang).

Tuy nhiên, một trong các thông số bắt buộc có thể có độ dài thay đổi và điều này làm tôi lo lắng. Vì tôi đã mã hóa tất cả các tham số trong chuỗi truy vấn của yêu cầu GET, có vẻ như với tôi rằng điều này đã đặt một số upper limit of (roughly) 2000 characters for the request URL không cần thiết. Và bất kể, tôi không thích nhìn thấy các URL yêu cầu dài 500 ký tự.

Vì vậy, vì yêu cầu POST không có giới hạn như vậy nên tôi đã quyết định chuyển đổi. Nhưng điều này không cảm thấy đúng. Tôi theo ấn tượng rằng một POST biểu thị sửa đổi dữ liệu - nhưng tôi đang sử dụng nó cho một yêu cầu chỉ đọc đơn giản.

Có cách nào tốt hơn để thực hiện việc này không? Để thực hiện một GET, với nhiều tham số? Tôi đã nghe nói về một phương pháp - nơi bạn thực hiện POST sơ bộ của các thông số và sau đó thực hiện GET. Tuy nhiên, kỹ thuật này lá nhiều để được mong muốn.

Nhưng nhìn qua trường hợp cụ thể này, ngữ nghĩa và giới hạn thực sự của phương thức yêu cầu HTTP là gì? Và tại sao GET không hỗ trợ bất kỳ loại tải trọng tham số nào? Sử dụng chuỗi truy vấn trong URL gần như cảm thấy giống như một hack với tôi.

+0

Tại sao bạn cảm thấy bài đăng đó biểu thị sửa đổi dữ liệu? –

+1

@ConradFrix: Bởi vì nó được sử dụng trong việc gửi biểu mẫu, trong việc tải lên tệp và [hành động không phải là idempotent chung.] (Http://en.wikipedia.org/wiki/POST_ (HTTP) #Affecting_server_state) – voithos

+0

Nếu bạn viết một ứng dụng Ajax, tại sao bạn quan tâm đến độ dài của URL?Cũng lưu ý rằng giới hạn ký tự 2000 chỉ áp dụng cho các URL trình duyệt, chứ không phải các yêu cầu Ajax (như đã lưu ý trong các nhận xét cho liên kết mà bạn đã trình bày). –

Trả lời

12

Một vài điểm về vấn đề này:

  • Các HTTP spec (RFC 2616) không forbit GET yêu cầu phải có các thông số, vì vậy nó không phải là một vấn đề của ngữ nghĩa của HTTP GET riêng của mình. Tuy nhiên, nhiều ngăn xếp HTTP (dành cho khách hàng, dịch vụ hoặc proxy) cấm các yêu cầu HTTP, thực tế là bạn không thể sử dụng chúng hầu hết là chi tiết triển khai (khá phổ biến) so với vấn đề ngữ nghĩa với yêu cầu HTTP GET
  • Tương tự, giới hạn của chiều dài URI (hoặc chuỗi truy vấn) cũng không được chỉ định trên RFC. Nó chủ yếu là giảm thiểu an ninh được thực hiện bởi một số ngăn xếp máy chủ HTTP để ngăn chặn một khách hàng xấu sử dụng tài nguyên máy chủ (ví dụ, trong IIS/ASP.NET giới hạn mặc định là 2k nhưng bạn có thể tăng nó thông qua một số phần tử trong web.config). Một lần nữa, nó không phải là một ngữ nghĩa mà là một vấn đề thực tế.
  • Yêu cầu POST chỉ ra sửa đổi dữ liệu nếu bạn đang theo triết lý REST, nhưng có nhiều ví dụ về yêu cầu HTTP POST được sử dụng cho các hoạt động chỉ đọc. SOAP sử dụng POST trong tất cả các yêu cầu của nó, bất kể hoạt động mà nó đang gọi là "an toàn" hay "sửa đổi". Vì vậy, bạn có thể sử dụng POST cho các hoạt động đó. Tuy nhiên, bằng cách lệch khỏi việc sử dụng REST (và "kinh điển"), bạn sẽ mất một số tính năng của giao thức, chẳng hạn như bộ nhớ đệm có thể được áp dụng cho các yêu cầu GET, chứ không phải cho POST.
  • Ví dụ của bạn về việc sử dụng hai yêu cầu (POST với tham số + GET để "nhận" kết quả) có vẻ quá mức cần thiết. Như tôi đã đề cập, yêu cầu POST không nhất thiết có nghĩa là sửa đổi tài nguyên, do đó bạn không phải tạo "giao thức" mới (POST + GET) để truy cập hoạt động của mình khi một yêu cầu là đủ.
+2

+1 câu trả lời hay, một điểm quan trọng khác: GET được cho là không có giá trị, vì vậy nó có thể (và được) tự động thử lại bởi khách hàng, POST không bao giờ được thử lại. –