在Internet Explorer中从二进制文件打开PDF

Open PDF from binary in Internet Explorer

本文关键字:PDF 二进制文件 Internet Explorer      更新时间:2023-09-26

与需要在IE窗口中打开blob/PDF和AngularJS中的Setting window.location或window.open相关;访问被拒绝";在IE 11中。

我需要打开一个PDF,它来自我的服务中的字节数组:

@RequestMapping("/{dokumentId}")
public ResponseEntity<byte[]> getDoc(@PathVariable Integer docId, HttpServletRequest request, HttpServletResponse response) throws IOException {       
    byte[] contents = // .. get document 
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.parseMediaType("application/pdf"));
    headers.add("Content-Disposition", "inline;filename=file");
    headers.add("Cache-Control","private, must-revalidate, post-check=0, pre-check=0, max-age=1");
    headers.add("Pragma", "no-cache");
    headers.setContentLength(contents.length);
    return new ResponseEntity<>(contents, headers, HttpStatus.OK);
}

我正试图用以下JS在InternetExplorer11中打开它:

$scope.openPdf = function(doc){
    var winlogicalname = "document_" + doc.docId;
    var winparams = 'dependent=yes,locationbar=no,scrollbars=yes,menubar=yes,resizable,screenX=50,screenY=50,width=850,height=1050';
    var ieEDGE = navigator.userAgent.match(/Edge/g);
    var ie = navigator.userAgent.match(/.NET/g); // IE 11+
    var oldIE = navigator.userAgent.match(/MSIE/g); 
    if(!ie && !oldIE && !ieEDGE){
        // Open PDF in new browser window
        var detailWindow = window.open("", winlogicalname, winparams);
    }
    xxxService.getDoc(doc).success(function(data){
        //for browser compatibility  
        if (ie || oldIE || ieEDGE) {
            var blob = new window.Blob([data], { type: 'application/pdf' });    
            window.navigator.msSaveOrOpenBlob(blob);
        } else {
            var binaryAsString = ArrayBufferToString(data).replace(/"/g,"");
            var pdfAsDataUri = "data:application/pdf;base64," + binaryAsString;
            var htmlText = '<embed width=100% height=100% type="application/pdf" src="'+ pdfAsDataUri + '"></embed>'; 
            detailWindow.document.write(htmlText);
            detailWindow.document.close();
        }   
    }).error(function(data, status, headers, config){
        console.log(data, status, headers, config);
    });
};

这适用于Chrome和Firefox(在新窗口中打开,直接用<embed>从二进制文件构建。然而,这种方式似乎在IE中不起作用,因此是msSaveOrOpenBlob。但在IE中保存/打开PDF时,我在Adobe Reader中遇到了一个错误:"Adobe Acrobat Reader DC could not open 'file.pdf' because it is either not a supported file type or because the file has been damaged (for example, it was sent as an email attachment and wasn't correctly decoded)."。当我试图将PDF拖放到IE时,它会显示"File does not begin with '%PDF-'."。

关于如何在IE11中直接使用字节数组或构建Blob打开PDF,有什么想法吗?

我将web服务更改为:

byte[] contents = // get contents
response.getOutputStream().write(contents);
response.setContentType("application/pdf");
response.setContentLength(contents.length);
response.addHeader("Content-Disposition", "inline;filename="+filename);
response.addHeader("Cache-Control", "private, must-revalidate, post-check=0, pre-check=0, max-age=1");
response.addHeader("Pragma", "public");

然后在客户端使用消费

Service.getDocument(docId).success(function(data){
    var file = new Blob([data], {type: 'application/pdf'});
    if(window.navigator.msSaveOrOpenBlob){
        window.navigator.msSaveOrOpenBlob(file, name + ".pdf");
    } else {
        var fileURL = URL.createObjectURL(file);
        $scope.renderPDF(fileURL, detailWindow.document.getElementById('canvas'));
    } 
}

其中CCD_ 6使用PDFJS在新窗口中渲染PDF。请记住在$http.get(或post)方法上设置{responseType:'arraybuffer'})