Tôi có một ứng dụng web một trang dựa trên jquery. Nó giao tiếp với một dịch vụ web RESTful thông qua các cuộc gọi AJAX.
Tôi đang cố gắng thực hiện như sau:
- Gửi một POST có chứa dữ liệu JSON đến một url REST.
- Nếu yêu cầu chỉ định một phản hồi JSON, thì JSON được trả về.
- Nếu yêu cầu chỉ định phản hồi PDF / XLS / etc, thì tệp nhị phân có thể tải xuống được trả về.
Bây giờ tôi có 1 & 2 hoạt động và ứng dụng jquery của khách hàng hiển thị dữ liệu được trả về trong trang web bằng cách tạo các phần tử DOM dựa trên dữ liệu JSON. Tôi cũng có # 3 làm việc theo quan điểm dịch vụ web, nghĩa là nó sẽ tạo và trả về một tệp nhị phân nếu được cung cấp các tham số JSON chính xác. Nhưng tôi không chắc chắn cách tốt nhất để xử lý số 3 trong mã javascript của máy khách.
Có thể lấy lại một tệp có thể tải xuống từ một cuộc gọi ajax như thế này không? Làm cách nào để tải xuống trình duyệt và lưu tệp?
$.ajax({
type: "POST",
url: "/services/test",
contentType: "application/json",
data: JSON.stringify({category: 42, sort: 3, type: "pdf"}),
dataType: "json",
success: function(json, status){
if (status != "success") {
log("Error loading data");
return;
}
log("Data loaded!");
},
error: function(result, status, err) {
log("Error loading data");
return;
}
});
Máy chủ trả lời với các tiêu đề sau:
Content-Disposition:attachment; filename=export-1282022272283.pdf
Content-Length:5120
Content-Type:application/pdf
Server:Jetty(6.1.11)
Một ý tưởng khác là tạo tệp PDF và lưu trữ nó trên máy chủ và trả về JSON có chứa URL cho tệp. Sau đó, đưa ra một cuộc gọi khác trong trình xử lý thành công ajax để thực hiện một số thao tác như sau:
success: function(json,status) {
window.location.href = json.url;
}
Nhưng làm điều đó có nghĩa là tôi sẽ cần thực hiện nhiều cuộc gọi đến máy chủ và máy chủ của tôi sẽ cần xây dựng các tệp có thể tải xuống, lưu trữ chúng ở đâu đó, sau đó định kỳ dọn sạch vùng lưu trữ đó.
Phải có một cách đơn giản hơn để thực hiện điều này. Ý tưởng?
EDIT: Sau khi xem xét các tài liệu cho $ .ajax, tôi thấy rằng dataType phản hồi chỉ có thể là một trong số đó xml, html, script, json, jsonp, text
, vì vậy tôi đoán không có cách nào để tải xuống trực tiếp một tệp bằng yêu cầu ajax, trừ khi tôi nhúng tệp nhị phân vào sử dụng Lược đồ URI dữ liệu như được đề xuất trong câu trả lời @VinayC (đây không phải là điều tôi muốn làm).
Vì vậy, tôi đoán các lựa chọn của tôi là:
Không sử dụng ajax và thay vào đó hãy gửi một bài đăng mẫu và nhúng dữ liệu JSON của tôi vào các giá trị của biểu mẫu. Có lẽ sẽ cần phải lộn xộn với iframe ẩn và như vậy.
Không sử dụng ajax và thay vào đó chuyển đổi dữ liệu JSON của tôi thành chuỗi truy vấn để xây dựng yêu cầu GET tiêu chuẩn và đặt window.location.href thành URL này. Có thể cần sử dụng event.preventDefault () trong trình xử lý nhấp chuột của tôi để ngăn trình duyệt thay đổi từ URL ứng dụng.
Sử dụng ý tưởng khác của tôi ở trên, nhưng được tăng cường với các đề xuất từ câu trả lời @naikus. Gửi yêu cầu AJAX với một số tham số cho phép dịch vụ web biết điều này đang được gọi thông qua một cuộc gọi ajax. Nếu dịch vụ web được gọi từ một cuộc gọi ajax, chỉ cần trả lại JSON có URL cho tài nguyên được tạo. Nếu tài nguyên được gọi trực tiếp, sau đó trả về tệp nhị phân thực tế.
Càng nghĩ về nó, tôi càng thích lựa chọn cuối cùng. Bằng cách này, tôi có thể lấy lại thông tin về yêu cầu (thời gian tạo, kích thước tệp, thông báo lỗi, v.v.) và tôi có thể hành động theo thông tin đó trước khi bắt đầu tải xuống. Nhược điểm là quản lý tập tin thêm trên máy chủ.
Bất kỳ cách nào khác để thực hiện điều này? Bất kỳ ưu / nhược điểm nào đối với các phương pháp này tôi nên biết?
url = 'http://localhost/file.php?file='+ $('input').val(); window.open(url);
Cách dễ dàng để có được kết quả tương tự. Đặt tiêu đề trong tập tin php. Không cần gửi bất kỳ ajax hoặc nhận yêu cầu