因為一起讀論文網站的流出帶寬特別低,為了給用戶更好的體驗,在線打開pdf的時候,考慮采用兩條途徑:一條是按頁提供給用戶進行閱讀,減少帶寬占用,因為不是所有的用戶都全部頁面都看一遍;另一條是給出pdf的下載進度提示,用戶能夠有交互式的感知體驗。第一條限於技術原因,實現起來較為復雜;因此先實現了第二條途徑。
從網站的技術角度來看,前端頁面對服務器發出ajax請求,服務器收到請求后讀取對應pdf,通過Nodejs的Stream方式回傳給頁面。下面的代碼顯示了通過jquery發送ajax請求,並在控制台顯示進度信息
1 $.ajax({ 2 url: '/api/version', 3 type: 'post', 4 dataType: 'json', 5 data: { paperid: paperid, version: filename }, 6 statusCode: { 7 200: function (json) {}, 8 }, 9 xhr: function(){ 10 var xhr = new window.XMLHttpRequest(); 11 //download progress 12 xhr.addEventListener("progress", function (evt) { 13 if (evt.lengthComputable) { 14 var percentComplete = evt.loaded / evt.total; 15 console.info("progress: "+Math.round(percentComplete * 100)+"%"); 16 } 17 }, false); 18 return xhr; 19 } 20 });
如果evt.lengthComputable為false,一般是由於服務器沒有設置數據包的長度導致的。因此,在服務器端回傳的代碼片段如下:
1 const s = new Readable(); 2 s.push(blob); 3 s.push(null); 4 res.set({ 5 'Accept-Ranges':'bytes', 6 'Content-Type': 'application/octet-stream', 7 'Content-Disposition': 'attachment; filename=' + paperid + '.pdf', 8 'Content-Length': blob.length 9 }); 10 s.pipe(res);
Content-Length即是下載文件的總長度
參考資料:
http://api.jquery.com/jQuery.ajax/
https://stackoverflow.com/questions/22502943/jquery-ajax-progress-via-xhr