2009-07-05 15 views
15

Này, bạn đang gửi một hình thức, mà ảnh hưởng đến cơ sở dữ liệu của bạn (thêm ghi/xóa chúng/cập nhật) và đây là cách yêu cầu của bạn trông giống như:Bạn có luôn ĐỔI MỚI sau POST? Nếu có, Làm thế nào để bạn quản lý nó?

POST/application/action = cập nhật

Bây giờ, nói rằng, bạn đã hoàn tất cập nhật của mình, vì vậy bạn muốn đưa người dùng đến trang chủ.

Response.sendRedirect/application/action = home

Điều này làm việc tuyệt vời. Người dùng được gửi chuyển hướng sau POST, vì vậy ngay cả khi người dùng cố gắng làm mới trang bằng cách nhấn F5, bạn vẫn tốt. Tuy nhiên, điều này sẽ không hoạt động nếu bạn đã làm điều này:

requestDispatcher.forward (/ application/action = nhà)

Cho rằng có một kịch bản mà bạn có để hiển thị các loại khác nhau của các thông báo lỗi/thành công sau khi bạn được thực hiện với bản cập nhật của bạn, bạn có nhiều khả năng thực hiện chuyển tiếp sau POST. Trong trường hợp như vậy, làm thế nào để bạn tránh các hành động cập nhật xảy ra hai lần?

Tôi thấy khá thú vị rằng nhiều trang web an toàn (ngân hàng)/cổng thanh toán có xu hướng thông báo cho người dùng bằng cách đặt văn bản trên màn hình, chẳng hạn như "Vui lòng không nhấn nút quay lại/làm mới".

Không có cách nào tốt hơn để xử lý việc này? Khác với yêu cầu người dùng không nhấn các nút này? Khi tôi kiểm tra lần cuối, có một cái gì đó được gọi là 'Bộ đệm đáp ứng dọc'. Bộ lọc sẽ xác định tính duy nhất của yêu cầu của bạn trong một phiên và cố gắng gửi phản hồi được lưu trong bộ nhớ cache nếu yêu cầu trùng lặp. Có cách nào đơn giản hơn để giải quyết vấn đề kinh điển này không?

Đây là liên kết đến giải pháp bộ nhớ cache phản hồi theo chiều dọc mà tôi đã nói về: http://www.fingo.info/en/articles/_1.html. Tôi, Tuy nhiên, không chắc chắn như thế nào này thực sự hoạt động.

+0

Khi tôi nghĩ về nó, tôi nhận thấy rằng stackoverflow, làm một cái gì đó tương tự. Khi bạn chỉnh sửa bài đăng của mình và lưu thay đổi, bạn sẽ được chuyển hướng trở lại bài đăng của mình. Bây giờ, điều gì sẽ xảy ra nếu bạn hiển thị thông báo "Các chỉnh sửa của bạn đã thành công"? (Tôi biết nó có vẻ hơi què, nhưng điều này thường được gọi là 'trải nghiệm duyệt web cho những người sử dụng câm không bị thách thức trực quan'). Để hiển thị thông báo này, bạn phải biết rằng lưu của bạn đã trôi qua tốt, ngoài việc gửi một chuỗi dài thực sự trong chuỗi truy vấn của bạn và chuyển hướng, cách duy nhất bạn sẽ làm là FORWARD? – Jay

Trả lời

1

Một ý nghĩ mà tôi đã có là nhúng một ID duy nhất (có thể là một chuỗi ngẫu nhiên) dưới dạng trường biểu mẫu ẩn trong biểu mẫu đang được gửi POST. Chuỗi ID có thể được đặt trong cơ sở dữ liệu dưới dạng "ID giao dịch". Bây giờ, khi bạn đi cập nhật cơ sở dữ liệu, trước tiên hãy kiểm tra xem có bản ghi hiện có với ID giao dịch đã gửi hay không và nếu có, giả sử nó là bản sao và không thay đổi cơ sở dữ liệu.

Tất nhiên, như tôi đã nói, đây chỉ là một ý nghĩ. Tôi không biết phương pháp nào thực sự được sử dụng trong thực tế. (Tôi nghi ngờ rằng rất nhiều các trang web ít quan trọng chỉ cần bỏ qua các vấn đề và hy vọng người dùng của họ sẽ được thông minh ... một đề xuất mất nếu tôi đã từng nhìn thấy một ;-)

EDIT: như đã chỉ ra trong các ý kiến , lưu trữ ID giao dịch trong cơ sở dữ liệu có thể chiếm nhiều không gian, nhưng nếu đó là vấn đề, bạn có thể lưu bộ nhớ cache trong tất cả các ID giao dịch được xử lý trong 5 phút/1 giờ/1 ngày/bất kỳ. Điều đó sẽ hoạt động trừ khi bạn chống lại một hacker được xác định ...

+1

Tôi nghĩ rằng sẽ tốn quá nhiều chi phí để chạy cơ sở dữ liệu mỗi lần giao dịch. Đối với một ứng dụng với hàng triệu người dùng, nó sẽ là hàng triệu 'chỉ vì lợi ích của nó' hồ sơ - suy nghĩ về làm sạch và duy trì một bảng này. – Jay

+0

@Jay, nah - bạn chỉ cần thêm một giao dịch UNIQUE fieldID trên bất kỳ bảng hoặc khung nhìn nào có liên quan, và REPLACE HOẶC IGNORE - ta-da! -) –

+0

@Alex Cách tiếp cận phi cơ sở dữ liệu cho vấn đề này? Điều gì về cookie? – Jay

12

Có, tôi tin rằng bạn nên chuyển hướng sau POST, ngoại trừ các yêu cầu API. Nếu không làm điều này không chỉ làm bạn phải lo lắng về việc POST trùng lặp khi người dùng sử dụng nút quay lại, nhưng trình duyệt cũng sẽ cung cấp cho người dùng các hộp thoại gây phiền nhiễu khi họ cố gắng sử dụng nút quay lại.

Response.sendRedirect hoạt động trong thực tế, nhưng về mặt kỹ thuật, việc này đang gửi mã phản hồi HTTP sai cho mục đích này. sendRedirect gửi 302, nhưng mã chính xác để sử dụng để chuyển POST thành GET là 303.(hầu hết các trình duyệt sẽ xử lý 302 giống như 303 nếu chúng nhận được phản hồi đối với POST), tuy nhiên)

Nói chung, bạn muốn chuyển hướng để đưa người dùng đến bất kỳ chế độ xem nào sẽ hiển thị ảnh hưởng của thay đổi của họ. Ví dụ: nếu họ chỉnh sửa tiện ích con, họ sẽ được chuyển hướng đến chế độ xem của tiện ích đó. Nếu họ xóa một tiện ích, họ sẽ được chuyển hướng đến chế độ xem mà tiện ích sẽ xuất hiện khi nó tồn tại (có thể là danh sách tiện ích con).

Thỉnh thoảng bạn có một thông báo trạng thái để tiếp tục lái xe về nhà thực tế là một hành động đã xảy ra. Cách đơn giản để thực hiện việc này là có thông số chung cho các chế độ xem của bạn, khi được đặt, sẽ hiển thị thông báo hoàn thành tác vụ. ví dụ:

/widget?id=12345&msg=Widget+modified. 

Ở đây thông số "msg" chứa thông báo "Widget đã sửa đổi". Nhược điểm của phương pháp này là các trang web độc hại có thể khiến người dùng của bạn nhầm lẫn/gây hiểu lầm. ví dụ:

/account?msg=Foo+Corp.+hates+you. 

Nếu bạn thực sự lo lắng về điều này, bạn có thể bao gồm chữ ký hết hạn cho thông báo làm thông số bổ sung. Nếu chữ ký không hợp lệ hoặc đã hết hạn, chỉ cần không hiển thị thông báo.

+0

@Laurence Bạn sẽ làm gì nếu phải hiển thị nhiều thư? Ba loại: Thành công, Thất bại và Cảnh báo? Nó chắc chắn phải được thông qua trong phạm vi yêu cầu cho hành động của bạn mà làm cho Widget View của bạn. – Jay

+0

Chắc chắn. Đó chỉ là một phần mở rộng cho tham số msg mà tôi đã mô tả. –

+0

@Laurence vì vậy bạn đang nói rằng tôi sẽ có một cái gì đó như thế này: msg = Foo + Corp + bất cứ điều gì & msgType = Thành công Đồng ý. Làm thế nào về nhiều tin nhắn của các loại khác nhau? Các công cụ như thế này dễ dàng hơn để đại diện trong các đối tượng hoặc bạn đang xem xét một công việc rất khó khăn khi lắp ráp các httpparameters – Jay

1

Tôi thấy khá thú vị rằng nhiều trang web an toàn (ngân hàng)/cổng thanh toán có xu hướng thông báo cho người dùng bằng cách đặt văn bản trên màn hình, chẳng hạn như "Vui lòng không nhấn nút quay lại/làm mới".

một số người tìm thấy nó tốt hơn để "vô hiệu hóa tất cả Quay lại, Làm mới sự kiện trên các trang quan trọng này"; Tôi không chắc liệu điều này có tốt hay không.

Nhưng giải pháp giải quyết của bạn "phản ứng dọc bộ nhớ cache" âm thanh đẹp

+0

@Ali tắt các sự kiện quay lại/làm mới? Làm thế nào để bạn vô hiệu hóa nút quay lại của trình duyệt/F5 ?? Tôi đã nghe nói về các lập trình viên đang cố gắng làm những điều như vậy và thất bại thảm hại. – Jay

+0

Thực ra tôi đã không làm điều đó bằng tay, nhưng tôi thấy bạn bè nói về việc xóa các nút làm mới và quay lại từ trình duyệt trong các trang quan trọng. Và liên quan đến vô hiệu hóa F5 Tôi tìm thấy mã này đoạn mã nhưng khi để vô hiệu hóa phím F5, viết kịch bản này trong phần đầu:

+0

mã trên niêm yết tại http://p2p.wrox.com/javascript-how/35830-disable-browser-f5-key.html nhưng tôi đoán các trường hợp như cắt ngắn firefox nên được xử lý Ctrl + R nhưng như tôi đã nói với bạn trước đây tôi tìm thấy "bộ nhớ cache phản hồi dọc" nghe có vẻ tốt đẹp của bạn với giải pháp được đề xuất này. –

1

của nó một chút không rõ ràng nhưng:

  • tạo ra một đối tượng có khóa trong user session.
  • giá trị là Yêu cầu + tương lai java cho kết quả
  • trả về ngay lập tức với chuyển hướng phía máy khách.
  • trong khi chuyển hướng phía máy khách đang được xử lý, yêu cầu chuỗi công nhân tạo ra câu trả lời.

Do đó, khi trình duyệt khách hoàn tất chuyển hướng, nhận hình ảnh của trang mới, v.v ... kết quả đang chờ người dùng.

Cách thay thế là làm cho người dùng nhận thức đau đớn về cơ sở dữ liệu mất bao lâu.

Security Update (2011 ngày 24 tháng 1):

Điều quan trọng là dễ bị tấn công vì nó là một phần của câu trả lời cho khách hàng, vì vậy

  1. Tạo một khóa ngẫu nhiên
  2. Sử dụng id phiên của người dùng làm muối để tạo SHA-1
  3. Lưu cả khóa ngẫu nhiên và SHA-1 trong cơ sở dữ liệu bằng (,) làm khóa chính. (không có chỉ mục riêng biệt trên RANDOMKEY.
  4. Sử dụng cả RANDOMKEY và SHA-1 làm tra cứu db.
  5. Không lưu trữ Id phiên (tránh các vấn đề về quyền riêng tư với việc có thể thu thập nhiều mục nhập cho cùng một người dùng)
  6. Hết hạn sau 2-3 ngày. (Cho phép một công việc hàng ngày để làm sạch và tránh tạo ra các vấn đề cho các phiên người dùng kéo dài một thời gian dài)

Phương pháp này yêu cầu bất kỳ hacker nào biết cả id phiên và khóa ngẫu nhiên.

Cách tiếp cận này có vẻ quá mức cần thiết, nhưng cơ chế được chuyển hướng cứng có thể được sử dụng cho các tình huống như đặt lại mật khẩu.

2

Giải pháp tốt nhất để giải quyết vấn đề hiển thị thông báo trạng thái cho người dùng sau khi chuyển hướng POST để GET là sử dụng phiên người dùng.

Làm thế nào

Thêm thuộc tính vào phiên người dùng với giá trị là tập hợp các thông điệp được hiển thị. cho ví dụ.

userSession.put("success_messages", new HashSet<String>(){"Success", "Check your account balance"}); 
userSession.put("warning_messages", new HashSet<String>(){"Your account balance is low. Recharge immediately"}); 

Và có bộ lọc quét phiên người dùng cho các thuộc tính cụ thể này và xuất ra thư. Bộ lọc sẽ xóa các thuộc tính sau khi đọc một lần, vì các thông báo trạng thái thường chỉ được hiển thị một lần.

0

Nếu bạn đang làm việc với kịch bản lệnh phía máy chủ java và cũng sử dụng struts 2 thì bạn tham khảo liên kết này nói về sử dụng mã thông báo.

http://www.xinotes.org/notes/note/369/

Một dấu hiệu nên được tạo ra và lưu giữ trong phiên cho trang ban đầu render, khi yêu cầu được gửi cùng với các dấu hiệu cho lần đầu tiên, trong thanh chống hành động chạy một sợi với tên chủ đề như token id và chạy logic bất cứ điều gì khách hàng đã yêu cầu, khi khách hàng gửi lại yêu cầu tương tự, kiểm tra xem luồng vẫn đang chạy (thread.getcurrentthread(). bị gián đoạn) nếu vẫn chạy sau đó gửi chuyển hướng khách hàng 503.

Hãy nhìn vào ExecuteAndWaitInterceptor của struts 2code, logic của việc này kết hợp với token sẽ giúp bạn nhanh chóng bấm vào

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