2009-03-18 40 views
37

Tôi có một ứng dụng cung cấp danh sách dài các thông số cho một trang web, vì vậy tôi phải sử dụng POST thay vì GET. Vấn đề là khi trang được hiển thị và người dùng nhấp vào nút Quay lại, Firefox sẽ hiển thị cảnh báo:Ngăn nút Back hiển thị cảnh báo xác nhận POST

Để hiển thị trang này, Firefox phải gửi thông tin lặp lại bất kỳ hành động nào (chẳng hạn như tìm kiếm hoặc xác nhận đơn hàng) đã được thực hiện trước đó.

Vì ứng dụng được xây dựng theo cách ngược lại nên hoạt động khá phổ biến, điều này thực sự gây phiền toái cho người dùng cuối.

Về cơ bản, tôi muốn làm điều đó một cách trang này không:

http://www.pikanya.net/testcache/

Nhập điều gì đó, gửi, và nhấn nút Back. Không cảnh báo, nó chỉ quay trở lại.

Googling Tôi phát hiện ra rằng đây có thể là một lỗi trong Firefox 3, nhưng tôi muốn bằng cách nào đó có được hành vi này ngay cả sau khi họ "sửa" nó.

Tôi đoán nó có thể thực hiện được với một số tiêu đề HTTP, nhưng chính xác thì sao?

+0

Chỉ vì vậy tôi chắc chắn rằng tôi biết những gì đang xảy ra ở đây, bạn có thể dán nội dung của cảnh báo? –

+0

Trang bạn đã liên kết không loại bỏ cảnh báo. Tôi vẫn thấy: Xác nhận Để hiển thị trang này, Firefox phải gửi thông tin lặp lại bất kỳ hành động nào (chẳng hạn như tìm kiếm hoặc xác nhận đơn hàng) đã được thực hiện trước đó. [Gửi lại] [Hủy] – Sparr

+0

Không nếu bạn sử dụng Firefox 3.0.6 hoặc phiên bản tương tự. Bạn có thể có một trình duyệt mà nó đã được "cố định". –

Trả lời

27

Một chiều là chuyển hướng POST tới trang chuyển hướng đến GET - xem Post/Redirect/Get on wikipedia.

Giả sử POST của bạn là 4K dữ liệu biểu mẫu. Có lẽ máy chủ của bạn làm điều gì đó với dữ liệu đó thay vì chỉ hiển thị nó một lần và ném nó đi, chẳng hạn như lưu nó trong cơ sở dữ liệu. Tiếp tục làm điều đó, hoặc nếu đó là một hình thức tìm kiếm lớn tạo ra một bản sao tạm thời của nó trong một cơ sở dữ liệu bị thanh lọc sau một vài ngày hoặc trên một cơ sở LRU khi một giới hạn không gian được sử dụng. Bây giờ tạo ra một đại diện của dữ liệu có thể được truy cập bằng cách sử dụng GET. Nếu nó tạm thời, hãy tạo một ID cho nó và sử dụng nó làm URL; nếu đó là tập hợp dữ liệu cố định, nó có thể có ID hoặc thứ gì đó có thể được sử dụng cho URL. Trong trường hợp xấu nhất, một thuật toán như sử dụng url nhỏ có thể thu gọn một URL lớn thành một URL nhỏ hơn nhiều. Chuyển hướng POST để GET đại diện cho dữ liệu.


Lưu ý lịch sử, kỹ thuật này là established practice in 1995.

+1

Nhưng làm thế nào? Dữ liệu đầu vào lớn hơn 4kB và đầu ra trang phụ thuộc vào nó. –

+0

Có vẻ như tôi sẽ phải làm theo cách này, trừ khi có một số mẹo với bộ nhớ cache. –

+1

không sử dụng bất kỳ thủ đoạn nào và thực hiện chính xác cách mà Pete đề xuất. những gì tôi thích về giải pháp của ông là nó tuân theo các nguyên tắc REST đơn giản. –

3

Một cách để tránh cảnh báo/hành vi đó là thực hiện POST thông qua AJAX, sau đó gửi người dùng đến trang khác (hoặc không) một cách riêng biệt.

+1

Vâng, đó là kế hoạch dự phòng của tôi. Nhưng, nút BACK không hoạt động với AJAX, vì vậy tôi sẽ phải thực hiện "bộ xử lý ngược" của riêng mình trong trường hợp này, mà tôi muốn tránh. –

37

Xem quy tắc vàng của tôi về lập trình web ở đây:

Stop data inserting into a database twice

Nó nói: “Đừng bao giờ đáp ứng với một cơ thể đến một POST yêu cầu. Luôn thực hiện công việc và sau đó trả lời bằng tiêu đề Vị trí: để chuyển hướng đến trang được cập nhật để trình duyệt yêu cầu bằng GET ”

Nếu trình duyệt yêu cầu người dùng về đăng lại, ứng dụng web của bạn bị hỏng. Người dùng sẽ không bao giờ thấy câu hỏi này.

+0

Để tạo trang web tôi cần cung cấp khoảng 4k đầu vào. Tôi không thể làm điều đó với GET. Không có "công việc" để được thực hiện, đầu ra chính nó phụ thuộc vào các tham số được đưa ra.Điều duy nhất tôi nghĩ là tôi có thể lưu trữ 4k dữ liệu đó trong phiên PHP và truy xuất dữ liệu đó trong yêu cầu GET, nhưng nếu người dùng có ... –

+0

... tab mở ứng dụng của tôi, điều đó sẽ không hoạt động. –

+8

Có vẻ như Amazon không tuân thủ quy tắc vàng này –

1

Tôi có một ứng dụng cung cấp danh sách dài các tham số cho một trang web, vì vậy tôi phải sử dụng POST thay vì GET.Vấn đề là khi trang được hiển thị và người dùng nhấp vào nút Quay lại, Firefox sẽ hiển thị cảnh báo:

Lý do của bạn sai. Nếu yêu cầu không có tác dụng phụ, nó sẽ là GET. Nếu nó có tác dụng phụ, nó sẽ được POST. Sự lựa chọn không nên dựa trên số lượng các thông số bạn cần phải vượt qua.

+3

Không có tác dụng phụ, nhưng thông số là 4kB. Trong trường hợp bạn không biết, GET có giới hạn 1024 byte. –

+0

Loại tham số nào chiếm nhiều không gian? Có lẽ bạn có thể giải thích bối cảnh của ứng dụng của bạn thêm một chút? – troelskn

+0

Giả sử đó là tìm kiếm hình ảnh ngược lại, nơi dữ liệu bài đăng là hình ảnh. –

2

Tôi đã sử dụng biến Phiên để trợ giúp trong trường hợp này. Đây là phương pháp tôi sử dụng mà đã làm việc tuyệt vời cho tôi trong nhiều năm:

//If there's something in the POST, move it to the session and then redirect right back to where we are 
if ($_POST) { 
    $_SESSION['POST']=$_POST; 
    redirect($_SERVER["REQUEST_URI"]); 
} 

//If there's something in the SESSION POST, move it back to the POST and clear the SESSION POST 
if ($_SESSION['POST']) { 
    $_POST=$_SESSION['POST']; 
    unset($_SESSION['POST']); 
} 

Về mặt kỹ thuật bạn thậm chí không cần phải đặt nó trở lại thành biến gọi là $ _POST. Nhưng nó giúp tôi theo dõi những dữ liệu nào đến từ đâu.

0

Là giải pháp khác bạn có thể ngừng sử dụng chuyển hướng.

Bạn có thể xử lý và hiển thị kết quả xử lý cùng một lúc mà không cần cảnh báo xác nhận POST. Bạn chỉ cần thao tác các đối tượng lịch sử trình duyệt:

history.replaceState("", "", "/the/result/page") 

Xem full hoặc short trả lời

Các vấn đề liên quan