2012-02-08 33 views
48

Tôi muốn buộc trình duyệt tải xuống tệp pdf.Cách sử dụng Bố cục nội dung để buộc tệp tải xuống ổ cứng?

Tôi đang sử dụng đoạn mã sau:

<a href="../doc/quot.pdf" target=_blank>Click here to Download quotation</a> 

Nó làm cho trình duyệt mở pdf trong một cửa sổ mới, nhưng tôi muốn nó tải về vào ổ đĩa cứng khi người dùng nhấp nó.

Tôi thấy rằng Content-disposition được sử dụng cho điều này, nhưng làm cách nào để sử dụng trong trường hợp của tôi?

+1

Bạn kiểm soát tiêu đề như thế nào? – Oded

+2

bản sao có thể có của [Cách triển khai Content-Disposition: attachment?] (Http://stackoverflow.com/questions/8875949/how-to-implement-content-disposition-attachment) – Quentin

Trả lời

83

Trên đáp ứng HTTP nơi bạn đang trở về tập tin PDF, đảm bảo các tiêu đề bố trí nội dung trông giống như:

Content-Disposition: attachment; filename=quot.pdf; 

Xem content-disposition trên trang wikipedia MIME.

+6

tôi rất mới với Bố cục nội dung – krish

+21

@ krish - Tất cả chúng ta đều học ở đâu đó. – Oded

+0

@Oded: Và trong trường hợp tệp được mở cục bộ * (hoặc bất kỳ trường hợp nào khác không có máy chủ http) *? – user2284570

4

Với các trình duyệt gần đây bạn có thể sử dụng tải về thuộc tính HTML5 cũng như:

<a download="quot.pdf" href="../doc/quot.pdf">Click here to Download quotation</a> 

Nó được hỗ trợ bởi hầu hết các trình duyệt gần đây ngoại trừ MSIE11. Bạn có thể sử dụng một polyfill, một cái gì đó như thế này (lưu ý rằng đây là chỉ cho dữ liệu uri, nhưng là một khởi đầu tốt):

(function(){ 

    addEvent(window, "load", function(){ 
     if (isInternetExplorer()) 
      polyfillDataUriDownload(); 
    }); 

    function polyfillDataUriDownload(){ 
     var links = document.querySelectorAll('a[download], area[download]'); 
     for (var index = 0, length = links.length; index<length; ++index) { 
      (function (link){ 
       var dataUri = link.getAttribute("href"); 
       var fileName = link.getAttribute("download"); 
       if (dataUri.slice(0,5) != "data:") 
        throw new Error("The XHR part is not implemented here."); 
       addEvent(link, "click", function (event){ 
        cancelEvent(event); 
        try { 
         var dataBlob = dataUriToBlob(dataUri); 
         forceBlobDownload(dataBlob, fileName); 
        } catch (e) { 
         alert(e) 
        } 
       }); 
      })(links[index]); 
     } 
    } 

    function forceBlobDownload(dataBlob, fileName){ 
     window.navigator.msSaveBlob(dataBlob, fileName); 
    } 

    function dataUriToBlob(dataUri) { 
     if (!(/base64/).test(dataUri)) 
      throw new Error("Supports only base64 encoding."); 
     var parts = dataUri.split(/[:;,]/), 
      type = parts[1], 
      binData = atob(parts.pop()), 
      mx = binData.length, 
      uiArr = new Uint8Array(mx); 
     for(var i = 0; i<mx; ++i) 
      uiArr[i] = binData.charCodeAt(i); 
     return new Blob([uiArr], {type: type}); 
    } 

    function addEvent(subject, type, listener){ 
     if (window.addEventListener) 
      subject.addEventListener(type, listener, false); 
     else if (window.attachEvent) 
      subject.attachEvent("on" + type, listener); 
    } 

    function cancelEvent(event){ 
     if (event.preventDefault) 
      event.preventDefault(); 
     else 
      event.returnValue = false; 
    } 

    function isInternetExplorer(){ 
     return /*@[email protected]*/false || !!document.documentMode; 
    } 

})(); 
+1

Dường như nó có hỗ trợ trình duyệt khá tốt ngoại trừ IE 11 và Safari di động: http://caniuse.com/#feat=download –

+0

@StephenOstermiller Các trình duyệt gần đây hỗ trợ các lớp học ES7 async/await và ES6 (ngoại trừ MSIE ofc.) Các trang công cộng có thể được tối ưu hóa cho MSIE trong khi các trang quản trị có thể được tối ưu hóa cho các trình duyệt khác với các tính năng mới. Hoặc bạn có thể sử dụng một polyfill MSIE. – inf3rno

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