2010-05-28 26 views
19

Tôi có biểu mẫu với tải lên tệp. Các tệp được tải lên thực sự là hình ảnh và video, vì vậy chúng có thể khá lớn. Tôi có logic dựa trên tiêu đề và 1KB đầu tiên có thể xác định xem phần còn lại sẽ được xử lý hoặc bị từ chối ngay lập tức. Trong trường hợp sau, tôi muốn chuyển hướng ứng dụng đến trang lỗi mà không phải chờ tải lên để hoàn tất.Chuyển hướng trước khi tải lên POST đã được hoàn thành

Trường hợp là, việc gửi trả lời trước khi POST hoàn tất dường như không hoạt động. Chuyển hướng bị bỏ qua và nếu tôi đóng kết nối, trình duyệt sẽ phàn nàn với Lỗi kết nối "Đặt lại kết nối theo đồng đẳng".

Vì vậy, câu hỏi đặt ra là: liệu có thể thực hiện điều đó trong HTTP thuần túy (không có JavaScript ở phía máy khách) hay không, và nếu có thì làm cách nào?

Trả lời

14

Giao thức HTTP/1.1 cho phép điều này, chỉ trong một cách thực sự kỳ lạ và sai lầm. Bạn cần phải áp dụng 3 bước sau proceedure:

  1. Ngay (đột ngột) đóng kết nối, lưu trữ một lá cờ server-side cho phiên client
  2. Sử dụng cờ phát hiện một nỗ lực để gửi lại dữ liệu hình thức tương tự , spec khuyến cáo khách hàng để làm điều này tự động
  3. Gửi tình trạng lỗi với một chuyển hướng (như 302 Tạm thời Moved)

này nên công việc vì như được nêu dưới đây khách hàng được dự kiến ​​sẽ thử lại một connec tion ít nhất một lần sau khi bị cắt bất ngờ. Vào lần thử lại, người ta dự kiến ​​sẽ chỉ gửi tiêu đề, sau đó chờ và xem phản hồi lỗi và hủy bỏ gửi cơ thể nếu nó nhận được.

http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html

8.2.4 Khách hàng Behavior nếu máy chủ non Đóng kết nối

Nếu một HTTP/1.1 client gửi một yêu cầu trong đó bao gồm một cơ quan yêu cầu, nhưng mà không bao gồm Expect trường tiêu đề yêu cầu với kỳ vọng "100 tiếp tục" và nếu khách hàng không được kết nối trực tiếp với máy chủ gốc gốc HTTP/1.1 và nếu khách hàng se es kết nối đóng trước khi nhận bất kỳ trạng thái nào từ máy chủ , khách hàng NÊN sẽ thử lại yêu cầu .Nếu khách hàng không thử lại yêu cầu này, nó có thể sử dụng sau đây "nhị phân mũ backoff" thuật toán để được đảm bảo có được một đáng tin cậy phản ứng:

1. Initiate a new connection to the server 

    2. Transmit the request-headers 

    3. Initialize a variable R to the estimated round-trip time to the 
    server (e.g., based on the time it took to establish the 
    connection), or to a constant value of 5 seconds if the round- 
    trip time is not available. 

    4. Compute T = R * (2**N), where N is the number of previous 
    retries of this request. 

    5. Wait either for an error response from the server, or for T 
    seconds (whichever comes first) 

    6. If no error response is received, after T seconds transmit the 
    body of the request. 

    7. If client sees that the connection is closed prematurely, 
    repeat from step 1 until the request is accepted, an error 
    response is received, or the user becomes impatient and 
    terminates the retry process. 

Nếu tại thời điểm bất kỳ một trạng thái lỗi được nhận được, client

- SHOULD NOT continue and 

    - SHOULD close the connection if it has not completed sending the 
    request message. 

Gotchas:

  1. Đó là những gì thông số kỹ thuật cho biết số người duyệt là NÊN. Ai biết được trình duyệt nào ACTUALLY do trong trường hợp này? Không phải tôi. Bạn sẽ cần phải chạy một số thử nghiệm.
  2. Thông số này đề cập cụ thể rằng hành vi này chỉ áp dụng "nếu khách hàng không được kết nối trực tiếp với máy chủ gốc HTTP/1.1". Điều đó có vẻ là một yêu cầu thực sự kỳ lạ trong thực tế có nghĩa là bạn có thể cần phải giả mạo các tiêu đề phản hồi của máy chủ để giả vờ bạn là máy chủ proxy hoặc HTTP/1.0.
  3. Một số giao thức trung gian nhất định như fast-cgi có thể không kích hoạt tập lệnh của bạn cho đến khi yêu cầu hoàn tất. Trong trường hợp này, bạn sẽ thực sự cần một máy chủ socket mức thấp thực sự.
  4. Toàn bộ quá trình này lộn xộn và phức tạp và thậm chí có thể không hoạt động. Bạn nên sử dụng AJAX tốt hơn theo ý kiến ​​của tôi. Tuy nhiên, bạn đã hỏi nếu nó có thể được thực hiện mà không có JS.
+0

Tôi phải nói, câu trả lời này khá hữu ích. Tuy nhiên, tôi nghi ngờ rằng tôi thậm chí sẽ cố gắng để thực hiện điều đó, như dịch vụ tôi có nói chung là phi trạng thái và đằng sau cân bằng tải không dính. – vartec

3

Hãy xem vé django #10850 - "Impossible to stop a large file upload mid-stream". Không giải quyết vấn đề, nhưng ít nhất nó sẽ giúp bạn hiểu nó.

+0

Theo như tôi có thể thấy, họ đang nói hoặc dừng xử lý ở phía máy chủ hoặc đặt lại kết nối, không phải là lựa chọn tốt cho tôi, bởi vì không cho phép chuyển hướng ngay lập tức. – vartec

+0

Tôi nghĩ rằng báo cáo lỗi ít nhất là câu trả lời cho câu hỏi của bạn về việc có thể thực hiện nó với HTTP thuần túy hay không, nhưng có lẽ tôi không đủ thông minh :). Javascript không phải là một tùy chọn hay bạn chỉ đang cố tránh sử dụng nó nếu bạn không phải làm vậy? – sdolan

+0

Cần thiết để hoạt động trên nhiều loại thiết bị di động, thực sự không bao gồm iPhone, BB và Android, ứng dụng này có ứng dụng gốc. Giả sử là, có JS không được bảo đảm. – vartec

-1
  1. sử dụng PCEL uploadprogress mở rộng nếu bạn sử dụng apache
  2. tạo ra một tập tin để thăm dò ý kiến ​​meta thông qua Ajax, và trở trueor sai dựa trên tình trạng của bạn, bạn cũng có thể nhận được các tập tin temp_name và kiểm tra các meta 1kb .
  3. cuộc gọi ajax cần được liên kết với một chức năng sử dụng tiêu đề làm mới meta HTML để chuyển hướng hoặc ở lại cho đến khi quá trình tải lên hoàn tất.


Kiểm tra ví dụ về tải lên.

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