2012-05-09 56 views
17

Tôi có một yêu cầu bất thường. Về cơ bản tôi cần một cách để khi người dùng nhấp vào một liên kết hoặc nút, họ sẽ nhận được một tệp PDF. Phần khó khăn ở đây là máy chủ sẽ không xử lý yêu cầu ở tất cả trừ khi tiêu đề tùy chỉnh được gửi cùng với nó (nếu không thì có vẻ như người đó đã đăng xuất và gửi chúng tới màn hình đăng nhập).Yêu cầu tệp có tiêu đề tùy chỉnh

Hiện tại, cách thức hoạt động của tiêu đề không thể thay đổi được, do đó, đừng ở trên đó; nó sẽ bị thay đổi trong tương lai và là một ứng dụng nội bộ mà tôi không kiểm soát được.

Các tùy chọn Tôi đã khám phá:

  • Sử dụng iframe hoặc đơn giản là mở một cửa sổ mới với một số loại con đường đó sẽ trở lại với PDF. Điều này không thể làm việc vì tôi không thể chỉ định tiêu đề bắt buộc cho tệp PDF và sẽ được chuyển hướng trước khi tiếp cận bản thân PDF.
  • Sử dụng biểu mẫu và gửi yêu cầu không thể hoạt động vì tôi không thể thêm bất kỳ tiêu đề tùy chỉnh nào vào biểu mẫu (chỉ XHR và plugin có thể, AFAIK).
  • Sử dụng XHR không thể làm việc vì, trong khi nó có thể thêm tiêu đề và truy xuất tệp, không có cách nào để lưu tệp đó ở phía máy khách.

Nó sẽ xuất hiện tùy chọn duy nhất của tôi vào thời điểm này cơ bản là:

  • Sử dụng một số loại plugin như Flash hoặc Silverlight để yêu cầu các tập tin.
  • Buộc thay đổi yêu cầu sớm hơn dự kiến ​​để tiêu đề không còn cần thiết nữa.

Có điều gì tôi thiếu ở đây không? Tôi hy vọng một người nào đó có thể xác minh những phát hiện của tôi hoặc chỉ cho tôi một cái gì đó tôi đã bỏ lỡ bởi vì, theo như tôi có thể nói, không thực sự bất cứ điều gì tôi có thể làm ở đây.

EDIT: Điều này có vẻ apt và khẳng định những gì tôi đã suy nghĩ: XMLHttpRequest to open PDF in browser

+2

Cách thêm một số loại đường hầm giữa ứng dụng và tập lệnh của bạn? Đường hầm có thể truy vấn ứng dụng và nhận tệp, sau đó đặt tiêu đề phù hợp trước khi xóa tệp cho người dùng, do đó thực sự kích hoạt tải xuống. Tôi không biết nếu điều này là có thể cho hệ thống của bạn, tùy thuộc vào an ninh. –

+0

Một đường hầm không phải là một ý tưởng tồi mặc dù tôi không chắc chắn chúng tôi có thể thực hiện điều đó ở đây. Hmm. Cảm ơn, tôi sẽ xem xét nó. – Kris

+1

Nếu bạn có thể làm mà không cần hỗ trợ cho IE <10 (không phải rất có thể, phải không?), Bạn có thể sử dụng các URL XMLHttpRequest Cấp 2 (XHR2) và Blob. Dưới đây là ví dụ: http://stackoverflow.com/q/9620497 Xem thêm http://stackoverflow.com/q/6165266 và http://www.html5rocks.com/en/tutorials/file/xhr2/ –

Trả lời

13

thử nghiệm để làm việc trong chrome:

function toBinaryString(data) { 
    var ret = []; 
    var len = data.length; 
    var byte; 
    for (var i = 0; i < len; i++) { 
     byte=(data.charCodeAt(i) & 0xFF)>>> 0; 
     ret.push(String.fromCharCode(byte)); 
    } 

    return ret.join(''); 
} 


var xhr = new XMLHttpRequest; 

xhr.open("GET", "/test.pdf"); //I had test.pdf this on my local server 


xhr.addEventListener("load", function(){ 
    var data = toBinaryString(this.responseText); 
    data = "data:application/pdf;base64,"+btoa(data); 
    document.location = data; 
}, false); 

xhr.setRequestHeader("magic", "header"); 
xhr.overrideMimeType("application/octet-stream; charset=x-user-defined;"); 
xhr.send(null); 

Bạn có thể thay đổi application/pdf để application/octet-stream có tải nhanh chóng. Nhưng nó khá dễ dàng để tải xuống từ trình đọc của chrome.

Trong firefox không có gì xảy ra, tôi đoán đó là vì tôi không có plugin để xử lý application/pdf được cài đặt.Thay đổi thành ứng dụng/octet-stream sẽ nhắc một dl.

Với IE Tôi cho rằng bạn cần một số loại VBScript/ActiveX hackery

Nếu tập tin là rất lớn, sử dụng dữ liệu uri có thể sụp đổ các trình duyệt, trong trường hợp đó bạn có thể sử dụng BlobBuilder và Object URL.

+1

Có thể đặt tên tệp tùy chỉnh để tải xuống không? –

2

Thay vì liên kết đến tập tin .PDF, thay vì làm một cái gì đó giống như

<a href="pdf_server.php?file=pdffilename">Download my eBook</a> 

mà kết quả đầu ra một tiêu đề tùy chỉnh, mở PDF (nhị phân an toàn) và in dữ liệu vào trình duyệt của người dùng, sau đó họ có thể chọn lưu tệp PDF bất kể cài đặt trình duyệt của họ. Các pdf_server.php sẽ trông như thế này:

header("Content-Type: application/octet-stream"); 

$file = $_GET["file"] .".pdf"; 
header("Content-Disposition: attachment; filename=" . urlencode($file)); 
header("Content-Type: application/force-download"); 
header("Content-Type: application/octet-stream"); 
header("Content-Type: application/download"); 
header("Content-Description: File Transfer");    
header("Content-Length: " . filesize($file)); 
flush(); // this doesn't really matter. 
$fp = fopen($file, "r"); 
while (!feof($fp)) 
{ 
    echo fread($fp, 65536); 
    flush(); // this is essential for large downloads 
} 
fclose($fp); 

EDIT: Cách duy nhất để thêm tiêu đề cho một yêu cầu từ bên trong một trình duyệt (client-side) là sử dụng phương pháp XmlHttpRequest setRequestHeader.

xhr.setRequestHeader('custom-header', 'value'); 
+0

Đây thực chất là suy nghĩ đầu tiên của tôi, tuy nhiên, tiêu đề phải được thêm vào phía máy khách vì máy chủ chỉ đơn giản là sẽ không xử lý bất cứ điều gì mà không có tiêu đề cho biết. Vì vậy, trừ khi tôi sử dụng một cái gì đó ở giữa khách hàng của tôi và kiến ​​trúc máy chủ hiện tại, không có phía máy chủ nào được thực hiện. – Kris

+0

Bạn không cần phải thêm tiêu đề phía máy khách. Điều này sẽ làm việc miễn là hoàn toàn không có văn bản trước tiêu đề trong tệp php. –

+0

Tôi nghĩ rằng bạn hiểu sai yêu cầu của tôi. Máy chủ tạo PDF yêu cầu tiêu đề tùy chỉnh được gửi cùng với tất cả các yêu cầu. Nếu tiêu đề không được gửi thì người ta cho rằng người dùng đã đăng xuất, không có mã phía máy chủ nào được chạy và người đó được chuyển hướng đến màn hình đăng nhập. Tôi đang cố gắng xác nhận những phát hiện của mình vì tôi tin rằng tôi vô cùng hạn chế trong việc chứng minh một giải pháp tốt. – Kris

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