【发布时间】:2017-08-14 06:11:18
【问题描述】:
我正在尝试使用 jquery ajax 调用从 WCF REST 服务下载 pdf 文件,但我认为存在编码问题。
这是服务接口方法定义
[OperationContract]
[WebInvoke(
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
Method="POST",
UriTemplate = "DownloadFile")]
Stream DownloadFile(RequestDownloadFile fileDownload);
然后是实现
public Stream DownloadFile(RequestDownloadFile fileDownload)
{
DBCepPortaleEntities cepPortale = CEP.DAL.DbConnections.GetConnessionePortale(ConnString); //connection with entity framework to SQLServer DB
var cerco = from cc in cepPortale.WEB_DOCUMENTI
where cc.IdDocumento == fileDownload.ID
select cc; //retrieving a Pdf VARBINARY Field
if (cerco.Count() > 0)
{
WEB_DOCUMENTI doc = cerco.First();
String nomeFile = @"test.pdf";
String tmp = Encoding.Default.GetString(doc.DocPDF);
File.WriteAllText(nomeFile, tmp, Encoding.Default);//test: pdf file is written correctly and I can read it
WebOperationContext.Current.OutgoingResponse.ContentType = "application/pdf";
WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-disposition", "inline; filename=circolare" + fileDownload.ID + ".pdf");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Transfer-Encoding", "binary");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Content-Encoding", "none");
FileStream f = new FileStream(nomeFile, FileMode.Open);
int length = (int)f.Length;
WebOperationContext.Current.OutgoingResponse.ContentLength = length;
byte[] buffer = new byte[length];
int sum = 0;
int count;
while ((count = f.Read(buffer, sum, length - sum)) > 0)
{
sum += count;
}
f.Close();
return new MemoryStream(buffer);
}
else
return null;
}
此方法正确写入名为“test.pdf”的pdf文件。
现在我正在尝试通过 ajax 调用来使用它:
$.ajax({
method: "POST",
url: "http://testwcfcircolari.bresciapaghe.it/Service.svc/DownloadFile",
data: '{"Token":"abc", "ID":"20"}',
contentType: "application/json",
success: function (response, status, xhr) {
console.log(response);
//self.settings.onSuccessStart(response, status, xhr, self);
// Check if a filename is existing on the response headers.
var filename = "";
var disposition = xhr.getResponseHeader("Content-Disposition");
if (disposition && disposition.indexOf("attachment") !== -1) {
var filenameRegex = /filename[^;=\n]*=(([""]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1])
filename = matches[1].replace(/[""]/g, "");
}
filename = "prova.pdf";
var type = xhr.getResponseHeader("Content-Type");
var blob = new Blob([response], { type: "application/pdf; charset=UTF-8" });
if (typeof window.navigator.msSaveBlob !== "undefined") {
// IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed.
window.navigator.msSaveBlob(blob, filename);
} else {
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
alert(filename);
if (filename) {
// Use HTML5 a[download] attribute to specify filename.
var a = document.createElement("a");
// Safari doesn"t support this yet.
if (typeof a.download === "undefined") {
window.location = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
}
} else {
window.location = downloadUrl;
}
//console.log(downloadUrl);
setTimeout(function () {
URL.revokeObjectURL(downloadUrl);
}, 100); // Cleanup
}
// Final custom event.
//self.settings.onSuccessFinish(response, status, xhr, self, filename);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('Error occurred while opening fax template' + XMLHttpRequest + " " +
+textStatus + " " + errorThrown);
}
});
结果是一个pdf文件,与原件有相同的页面,但内容都是空白的。 用文本编辑器观看下载的 pdf 的内容,与 starter 文件不同。
有什么建议吗? 谢谢。
【问题讨论】: