2016-02-24 17 views
5

Tôi đang làm việc với khung web (uPortal) đang xử lý lỗi bằng cách chỉ ném một ngoại lệ và sau đó treo. Khung làm việc bằng cách kết xuất XML thành HTML. Khi có ngoại lệ, trình duyệt sẽ lấy lại nội dung được hiển thị cho đến phần tử mẫu XML không thành công, và sau đó trình duyệt chỉ ngồi và đợi một thời gian chờ. Lý thuyết của nhóm chúng tôi là nội dung được gửi trước khi lỗi xảy ra, điều đó làm tôi ngạc nhiên. Các khung công tác khác mà tôi đã làm việc có vẻ như kết thúc hiển thị trước khi gửi nội dung.Chuyển hướng trang web sau khi đã gửi một số nội dung

Câu hỏi của tôi là, có cách nào để chuyển hướng trình duyệt sau khi nội dung đã được gửi không? Trong trường hợp này, chúng tôi đang ở giữa hiển thị nội dung của thẻ <script>, nhưng lỗi có thể xảy ra ở bất kỳ nơi nào trong html.

Suy nghĩ hiện tại của tôi là tiêm một số javascript ở đầu trang và cố gắng thay đổi hành vi của khung để thất bại nhanh chóng và đóng kết nối và thêm </body></html> thẻ khi xảy ra lỗi. Sau đó, javascript được đề cập ở trên sẽ chạy trên pageload và phát hiện nếu nội dung của toàn bộ trang đã có và làm một chuyển hướng phía khách hàng nếu không. Có lẽ nó có thể tìm kiếm một div ẩn đặc biệt ở cuối trang.

Có bất kỳ ví dụ nào về các khuôn khổ giải quyết vấn đề này một cách khác nhau hoặc của những người sử dụng khung làm việc tương tự xung quanh vấn đề này không?

Trả lời

0

Tôi không biết khuôn khổ đó, nhưng

Trong http, mỗi câu trả lời có một phản ứng mã liên kết với nó. Vì trang đã được chuyển giao một nửa/trả lại mã trạng thái (thường là "200") đã được gửi (và đã nhận) rồi.

Không có cách nào để trình duyệt chấp nhận mã phản hồi khác (như "301" để chuyển hướng) cho cùng một phản hồi! Ngoài ra, máy chủ không thể gửi mã phản hồi khác vì mã phản hồi ban đầu đã được cam kết và được gửi cho khách hàng.

Mô tả của bạn về lỗi và kiến ​​thức về giao thức http ngụ ý rằng có thể có một số lỗi triển khai trong các cấu phần khung/máy chủ được sử dụng, HOẶC nó đã được thực hiện một cách thận trọng, đe dọa tình huống hiện tại của bạn ...

0

để chuyển hướng một trang, bạn cần đặt thông tin chuyển hướng trong tiêu đề. nhưng bạn có thể viết tiêu đề khi bạn bắt đầu viết nội dung (có thể tiêu đề đã được nhận bởi khách hàng do thời gian bạn cạnh tranh bằng văn bản toàn bộ tài liệu)

Tuy nhiên, bạn có thể làm điều đó theo cách khác nhau như sau

1.let document loading complete and record if you need to redirect the page while rendering 
2. add a unique request-id identifier for each page load 
3. invoke ajax call with request-id (may be rest call) to server asking if page needs to be redirected. 
4. if page needs to be redirected , do so, via javascript in browser at client end. 
0

Phản hồi HTTP bao gồm tiêu đề và nội dung phản hồi tùy chọn. Khi bạn đã bắt đầu ghi phản hồi vào kết nối ổ cắm, bạn không thể hoàn nguyên nó. Trong ví dụ của bạn: Nếu bạn gặp lỗi ở giữa quá trình tạo nội dung, bạn không thể thêm tiêu đề chuyển hướng - phần tiêu đề đã được viết.

Tuyên bố trên không hoàn toàn đúng: trong HTTP chunked transfer encoding phản hồi được gửi theo các đoạn riêng biệt. Đoạn cuối cùng có thể có đoạn giới thiệu tùy chọn chứa các trường tiêu đề thực thể và về mặt lý thuyết là một tiêu đề chuyển hướng. Nhưng nếu bạn có thể sử dụng những cơ chế này là một câu hỏi khác. Ví dụ một thùng chứa servlet có thể sử dụng mã hóa chuyển chunked nhưng không cung cấp cho bạn một API để đặt đoạn giới thiệu.

Nhưng văn bản không được bắt đầu ngay lập tức: Ví dụ: HttpServletResponse duy trì bộ đệm cho nội dung phản hồi. Nếu bạn đặt tiêu đề và bắt đầu viết nội dung chỉ bộ đệm được lấp đầy và bạn vẫn có thể đặt lại phản hồi và bắt đầu lại. Nhưng khi bộ đệm tràn phản hồi được ghi vào kết nối và HttpServletResponse hiện là cam kết.

Cơ chế như vậy cung cấp cho bạn cách xử lý lỗi trong quá trình tạo nội dung diễn ra khi phản hồi chưa được khắc phục: Chỉ cần đặt lại phản hồi và gửi thông báo lỗi thay thế. Bạn có thể kiểm tra khung của bạn nếu nó hỗ trợ một cơ chế như vậy. Nhưng rõ ràng đây không phải là giải pháp cho các phản hồi lớn hơn.

Cách thứ hai để tránh lỗi trong quá trình tạo nội dung chỉ đơn giản là đảm bảo rằng chúng không thể xảy ra. Đầu tiên thu thập tất cả dữ liệu cần thiết cho phản hồi (ví dụ: thực hiện cuộc gọi cơ sở dữ liệu không an toàn), sau đó trong bước thứ hai tạo phản hồi - bước thứ hai là không không thành công (trừ khi bạn có lỗi trong mã của mình).

Bạn đã đề cập một cách thứ ba để xử lý lỗi, bằng cách yêu cầu khách hàng xử lý phản hồi và thực hiện một số hành động mà lỗi được phát hiện (ví dụ: bằng cách bao gồm tập lệnh trong phản hồi HTML được tạo).

+0

Các khung công tác khác giải quyết vấn đề này như thế nào? Giống như mùa xuân, ví dụ? Không phải chờ đợi cho đến khi các khung nhìn được hiển thị trước khi ghi vào phản hồi? Hay tất cả các khuôn khổ có vấn đề này? – xdhmoore

+0

@xdhmoore vào cuối mùa xuân cũng dựa trên công nghệ servlet, và theo như tôi biết sau chiến lược thứ hai được đề cập trong câu trả lời của tôi. Https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc này có thể được quan tâm, nhưng chủ yếu là về cách gửi đến trang lỗi có ý nghĩa và không phải cách tránh hoặc phục hồi từ một ngoại lệ. – wero

+0

Mùa xuân có cho phép bạn bắt ngoại lệ từ lớp xem/jsp không? Nơi mà tôi bối rối là trong khuôn khổ này, chúng tôi đang nhìn thấy các trang đóng băng tại trường hợp ngoại lệ sau khi tải tất cả các nội dung trước đó.Tôi đã nghĩ rằng các khung công tác khác như mùa xuân đã hiển thị mọi thứ trước khi bắt đầu trả lại nội dung (để họ có thể trả lại trang lỗi trong trường hợp ngoại lệ), nhưng khung này dường như bắt đầu trả lại nội dung trước khi hoàn thành. tùy chọn của bạn 3 ở trên lựa chọn duy nhất ... – xdhmoore

1

Bạn phải ghi lại lỗi hoặc chụp đầu ra trong bộ đệm. Nếu bạn có thể xử lý các ngoại lệ, có lẽ bạn có thể in một thẻ script đơn giản như

<script> window.location.href = 'some_new_url';</script> 

Nếu trình duyệt hiểu DOCTYPE là một cái gì đó liên quan đến HTML, nó sẽ thực hiện thẻ đó.

Nếu bạn có thể nắm bắt đầu ra trong bộ đệm, khi bạn xử lý lỗi, bạn có thể quyết định gửi chuyển hướng HTTP tới trình duyệt và hủy bộ đệm đầu ra đến điểm đó.

Đối với các frameowrks khác, trong PHP, bạn có thể chỉ cần kích hoạt bộ đệm đầu ra với ob_start(), sẽ không bắt đầu gửi nội dung cho đến khi yêu cầu được hoàn thành đầy đủ.

0

Cách đáng tin cậy duy nhất để thực hiện việc này là tạo đối tượng proxy HttpServletResponse lưu trữ phản hồi. Bạn sẽ cần phải cung cấp cho uPortal proxy này thay vì thực tế HttpServletResponse và chỉ gửi đầu ra bằng cách sử dụng phản hồi thực khi xử lý hoàn tất/gửi chuyển hướng nếu quá trình xử lý không thành công.

Đây là giới hạn thiết kế giao thức HTTP mà bạn không thể gửi chuyển hướng HTTP khi đầu ra đã được bắt đầu.

Các cách khác có thể dựa vào chuyển hướng HTML hoặc Javascript, nhưng vì bạn viết rằng lỗi có thể xảy ra bất cứ lúc nào, sẽ rất khó để in ra theo cách trình duyệt sẽ giải thích nó một cách đáng tin cậy.

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