我无法使用这种确切的方法来工作,所以我已经解决了这个问题。我可能已经接近我最初的尝试,所以我会分享它以防它有帮助 - 但我也会分享我的工作。
所以我的 .net 核心 web api 方法返回一个文件内容结果,如下所示:
return File(pdfBuffer, "application/pdf", fileName);
pdfBuffer 是一个字节[],后跟 MIME 类型和文件名。
在我的 Angular 数据服务 ts 文件中,我这样调用这个方法:
public generatePdf(param1) {
let body = {
"param1": param1
};
let pdfOptions = new RequestOptions();
pdfOptions.headers = this.options.headers;
pdfOptions.responseType = ResponseContentType.Blob;
return this.http.post("https://myWebsite/api/GeneratePdf", body, pdfOptions)
.map((res: Response) => res.blob());
}
我已重命名变量和方法名称等,但您可以看到我已将响应类型指定为 blob 并将响应映射为这样。我还从我正在使用的包含身份验证令牌的通用标头中复制了标头
在页面 ts 文件中调用它后,我订阅了,这就是我开始遇到问题的地方......
为了让 cordova 能够在我的 ts 文件中使用,我在项目根目录下的 tsconfig.json 文件中添加了以下内容:
"types": [
"cordova",
"cordova-plugin-file"
],
我还使用 npm 将 phonegap 和 cordova 库安装到我的项目中。
在页面的 ts 文件中,我在导入下添加了以下变量,以便我可以获取注入的 cordova 库:
declare var window: any;
declare var LocalFileSystem: any;
declare var device: any;
var storageLocation = "";
declare var cordova: any;
然后这个方法将blob保存或显示为pdf:
public generatePdf() {
let param1= param1Logic;
$("#waitingAnimation").show();
this.data.generatePdf(param1).subscribe(data => {
let fileName = "myDocument.pdf";
var blob = new Blob([data], { type: 'application/pdf' });
$("#waitingAnimation").hide();
//I tried to just open the pdf on the device like so... just get a blank white page on phonegap
//var fileURL = URL.createObjectURL(blob);
//window.open(fileURL); // if you want to open it in new tab
switch (device.platform) {
case "Android":
storageLocation = 'file:///storage/emulated/0/';
break;
case "iOS":
storageLocation = cordova.file.documentsDirectory;
break;
}
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
console.log('file system open: ' + fs.name);
let parentEntry = storageLocation + "Download/" + fileName;
fs.root.getFile(parentEntry, { create: true, exclusive: false }, function (fileEntry) {
fileEntry.createWriter(function (fileWriter) {
console.log('create writer');
fileWriter.onerror = function (e) {
console.log("Failed file write: " + e.toString());
};
fileWriter.write(blob);
});
}, null);
}, null);
});
}
这可能不是确切的代码——我做了很多修改而没有保存到存储库——所以我只是从我留在代码中的 cmets 粗略地把它放在一起。我没有收到任何控制台错误 - 它什么也没做。
我认为这与作为 blob 的响应有关,与白名单有关。我开始阅读它,发现它有安全隐患,我找不到任何描述如何使它安全的东西,所以此时我开始考虑其他解决方案。
所以我的工作...
我想我会尝试从另一个旧的 aspx 网站获取 pdf,该网站只需要对该 ashx 页面的简单获取请求,该页面只返回一个 pdf MIME 类型的 pdf 文件。我可以用 Angular 调用它,并使用以下代码在浏览器中打开 pdf:
window.open("https://myWebsite.ashx?fileName=" + fileName, '_system', 'location=no');
所以我所做的就是更改我的 Web API 来解决这个问题。
不是使用 post 来响应 blob,而是该 post 到服务器创建一个 pdf,该文件存储在服务器上的临时目录中 - 此 post 方法使用一些带有文件名的 JSON 响应。
然后我创建了另一个 Web API 方法,该方法接受一个以文件名作为参数(查询字符串)的 get 请求,这会查找该临时文件(我知道服务器位置,并且只需附加提供的文件名) - 如果文件存在我像以前一样用 FileContentResult 响应并从临时存储中删除文件。像这样:
[HttpGet]
[DeleteFileAttribute]
public IActionResult Get(string fileName)
{
var tempPath = $"serverLocationGoesHere/{fileName}";
byte[] fileBytes = System.IO.File.ReadAllBytes(tempPath);
return File(fileBytes, "application/pdf", fileName);
}
DeleteFileAttribute 是我为删除文件而创建的自定义属性。
所以现在在我的 dataService ts 文件中,我调用初始 GeneratePdf post 方法来生成 pdf:
public generatePdf(param1) {
let body = {
"param1": param1
};
return this.http.post("https://myWebSite/api/GeneratePdf", body, this.options)
.map((res: Response) => {
return res.json();
});
}
如您所见,这只是返回 JSON...
所以在我的页面 ts 文件中,我需要做的就是:
public generatePdf() {
let param1 = param1Logic;
$("#waitingAnimation").show();
this.data.generatePdf(param1).subscribe(data => {
let fileName = data.fileName;
$("#waitingAnimation").hide();
window.open("https://myWebsSite/api/DownloadFile?fileName=" + fileName, '_system', 'location=no');
}
现在我可以在我的 phonegap 应用程序中打开服务器生成的 PDF - 尽管不是按照我想要的方式。我确信有更好的方法也可以使用一些库打开 Pdf - 但希望这里有一些对某人有用的东西!