HTTP redirects
“Redirect” là một phần cơ bản của giao thức HTTP. Khái niệm này đã có và được ghi trong thông số kỹ thuật đầu tiên (RFC 1945), được xuất bản vào năm 1996, và nó vẫn được sử dụng phổ biến kể từ đó.
Redirect chính xác như ý nghĩa của từ: chuyển hướng.
Máy chủ gửi lại một hướng dẫn cho máy khách thay vì trả lại nội dung mà máy khách muốn. Máy chủ cho biết “hãy xem ở đây để tìm thứ mà bạn đã cần”.
Các redirect không giống nhau. Redirect tạm thời hay vĩnh viễn? GET
hay không GET
?
Tạm thời hay vĩnh viễn
Việc chuyển hướng có kéo dài hay chỉ có hiệu lực cho đến bây giờ?
- Nếu máy chủ muốn
GET
chuyển hướng vĩnh viễn người dùng đến tài nguyên B bằng mộtGET
khác, nó gửi mã301
. Điều đó cũng có nghĩa là trình duyệt ghi nhớ (lưu vào bộ nhớ cache) và luôn chuyển sang URI mới khi URI gốc được yêu cầu.
- Giải pháp thay thế tạm thời là
302
. Nếu máy chủ muốn máy khách gửi một yêu cầuGET
đến B, nhưng nó không cần ghi nhớ mà hãy tiếp tục thử URI ban đầu khi có yêu cầu lần sau.
Lưu ý rằng cả301
và302
sẽ khiến trình duyệt thực hiệnGET
trong yêu cầu tiếp theo, có nghĩa là có thể thay đổi phương thức nếu nó bắt đầu bằngPOST
.
Việc thay đổi phương thức HTTP thànhGET
cho phản hồi301
và302
này được cho là “vì lý do lịch sử”, nhưng đó vẫn là những gì các trình duyệt làm, hầu hết các trang web công cộng sẽ hoạt động theo cách này.
- Trên thực tế, mã
303
tương tự như302
. Nó sẽ không được lưu vào bộ nhớ cache và nó sẽ khiến máy khách đưa raGET
trong yêu cầu tiếp theo.
Sự khác biệt giữa302
và303
là rất nhỏ, nhưng303
dường như được thiết kế cho “phản hồi gián tiếp” đối với yêu cầu ban đầu hơn là chỉ chuyển hướng. Ba mã này là mã chuyển hướng duy nhất trong thông số kỹ thuật HTTP / 1.0.
Tuy nhiên, curl không nhớ hoặc lưu vào bộ nhớ cache bất kỳ chuyển hướng nào nên đối với nó, thực sự không có sự khác biệt giữa chuyển hướng vĩnh viễn và tạm thời.
Thông báo redirect cho curl
Thông thường curl chỉ thực hiện những điều cơ bản trừ khi chúng ta nói khác đi, nó không tuân theo các chuyển hướng HTTP theo mặc định.
Sử dụng tùy chọn -L, --location
để yêu cầu nó làm điều đó. Khi bật redirect, theo mặc định, curl sẽ theo dõi tối đa 50 chuyển hướng.
Giới hạn tối đa chủ yếu để tránh rủi ro bị mắc vào các vòng lặp vô tận. Nếu 50 không đủ, chúng ta có thể thay đổi số lượng chuyển hướng tối đa theo tùy chọn --max-redirs
.
GET hay POST
Tất cả ba mã phản hồi , 301
và 302/303
, sẽ giả định rằng máy khách gửi GET
để lấy URI mới, ngay cả khi máy khách có thể đã gửi POST
trong yêu cầu đầu tiên. Điều này rất quan trọng!
Thay vào đó, nếu máy chủ chuyển hướng máy khách đến một URI mới và muốn máy khách gửi cùng một phương thức trong yêu cầu thứ hai như trong yêu cầu đầu tiên, (thí dụ nếu lần đầu tiên máy khách gửi POST
, chúng ta muốn nó gửi lại POST
trong yêu cầu tiếp theo), máy chủ sẽ sử dụng các mã phản hồi khác nhau.
Để cho máy khách biết “URI mà bạn đã gửi POST
đến, được chuyển hướng vĩnh viễn đến B, cũng bằng phương thức POST
ngay bây giờ và trong tương lai”, máy chủ phản hồi bằng mã 308
. Và để làm phức tạp vấn đề, mã 308
chỉ mới xuất hiện gần đây (thông số kỹ thuật được xuất bản vào tháng 6 năm 2014) vì vậy các máy khách cũ có thể không xử lý nó một cách chính xác!
Mã phản hồi (cũ hơn) để yêu cầu máy khách gửi POST
cũng trong yêu cầu tiếp theo, nhưng tạm thời, là 307
. Tuy nhiên, chuyển hướng này sẽ không được lưu vào bộ nhớ cache. Mã 307
đã được giới thiệu trong HTTP / 1.1.
Redirects hoạt động theo cùng một cách trong HTTP / 2 như trong HTTP / 1.1.
Redirect | Permanent | Temporary |
Đổi sang GET | 301 | 302 và 303 |
Giữ phương thức gốc | 308 | 307 |
Chúng ta có thể yêu cầu curl không được thay đổi phương thức không-phải-GET
thành GET
sau phản hồi 30x bằng cách sử dụng các tùy chọn chuyên dụng: --post301
, --post302
và --post303
.
Thay vào đó, nếu chúng ta đang viết ứng dụng dựa trên libcurl, có thể kiểm soát hành vi đó bằng tùy chọn CURLOPT_POSTREDIR
.
Chuyển hướng sang host name khác
Khi sử dụng curl, chúng ta có thể cung cấp thông tin xác thực như tên người dùng và mật khẩu cho một trang web cụ thể, nhưng sau đó chuyển hướng HTTP sang một máy chủ lưu trữ khác.
Curl giới hạn những gì nó gửi đến các máy chủ khác so với bản gốc trong cùng một lần chuyển. Vì vậy, nếu chúng ta muốn thông tin đăng nhập cũng được gửi đến tên máy chủ tiếp theo không giống với tên gốc, chúng ta có thể nói với curl bằng cách sử dụng tùy chọn --location-trust
.