2017-09-11 31 views
0

我正在研究一個MEAN棧應用程序,並且我試圖在前端(Angular)中顯示來自後端(Express)的pdf。但是每次在傳輸過程中文件都會損壞。有人有想法嗎? 這裏是我的代碼(簡化):Express Angular - Serve PDF

後端:

import * as express from "express"; 
import * as fs from "fs"; 

myController.getPdf(req:express.Request, res:express.Response):void { 
    res.setHeader('Content-Type', 'application/pdf'); 
    res.setHeader('Content-Length', fs.statSync('myPdf.pdf').size); 
    fs.createReadStream('myPdf.pdf).pipe(res); 
} 

前端:

import {Http,ResponseContentType} from "@angular/http"; 

constructor(@Inject(Http) private _http:Http) {} 

this._http.get('ENDPOINT', {responseType: ResponseContentType.ArrayBuffer}) 
    .map(response => { 
     window.open(URL.createObjectURL(
      new Blob([response],{type:'application/pdf'}) 
))}); 

編輯:中間件:

import * as compression from "compression"; 
import * as zlib from "zbil"; 
import * as express from "express"; 
import * as bodyParser from "body-parser"; 
import * as session from "express-session"; 
import * as passport from "passport"; 
import * as morgan from "morgan"; 
import * as helmet from "helmet"; 

application: express.Application; 
let _root = process.cwd(); 

application.use(compression({ 
    level: zlib.Z_BEST__COMPRESSION, 
    threshold: "1kb" 
})); 
application.use(express.static(_root + "/node_modules/")); 
application.use(express.static(_root + "/jspm_packages/")); 
application.use(express.static(_root + "/client/dev/")); 
application.use(bodyParser.json()); 
application.use(session({ 
    secret: 'abcd', 
    saveUnitialized: true, 
    resave: true, 
})); 
application.use(passport.initialize()); 
application.use(passport.session()); 
application.use(morgan("dev")); 
application.use(helmet()); 

回答

0

我認爲你的「Content-Length」標題是無效的。文件系統的大小方法返回字符串的長度。

某些UTF-8字符包含多個字節。

更好的方法是使用http://nodejs.org/api/buffer.html的Buffer.byteLength(string,[encoding])。這是一個類方法,因此您不必創建任何Buffer實例。

+0

嗯......即使有這樣的變化,文件仍然在輸出不可讀。 我已經添加了使用的中間件,也許其中一個正在搞亂我的傳輸? –

1

Got it!

使用fs.statSync('myFile.pdf')。size作爲Content-Length運行良好。

問題是在另一端:響應對斑點()函數映射:

this._http.get(ENDPOINT, {responseType: ResponseContentType.ArrayBuffer}) 
    .map(response => { 
     window.open(URL.createObjectURL(
      new Blob(response.blob(), {type:'application/pdf'})); 
    });