问题描述
因此,当我尝试从服务器响应中保存文件时遇到问题.
So i have a problem when i tried to save file from server response.
当我尝试从浏览器中的url下载文件时,所有工作正常,但是当我尝试从clint端发送请求时,文件已保存,但文件中存在"[Object object]",并且如果是PDF文件无法打开.
When i try to download the file from url in my browser all work but when i tried to send request from the clint side the file is saved but in the file there is "[Object object]" and if it's a PDF file does not open.
请求中必须包含一个附加标头,其中包含客户端的密钥ID.
The request must include an additional header that contains the key ID of the client.
这是我的服务器代码:
[HttpGet, IsAllowed(4,PageAction.Download)]
public HttpResponseMessage Download(string id)
{
var path = HttpContext.Current.Server.MapPath("~") + string.Format(@"Files\{0}.doc",id);
var stream = new FileStream(path, FileMode.Open);
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = string.Format("{0}.doc", id);
return result;
}
这是我的克林特代码:
function get() {
var defer = $q.defer();
$http.post('http://localhost:4704/api/file/download/1', { responseType: 'arrayBuffer' }).then(
function (data, status, headers, config) {
var results = {
data: data,
headers: data.headers(),
status: data.status,
config: data.config
};
defer.resolve(results);
}, function (data, status, headers, config) {
defer.reject(data);
});
return defer.promise;
}
$scope.download = function () {
get().then(function (response) {
var octetStreamMime = 'application/octet-stream';
var fileName = "Test.doc";
var contentType = response.headers["content-type"] || octetStreamMime;
try {
var blob = new Blob([response.data], { type: contentType });
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, fileName);
} else {
var objectUrl = URL.createObjectURL(blob);
window.open(objectUrl);
}
} catch (exc) {
console.log("Save Blob method failed with the following exception.");
console.log(exc);
}
}, function (error) {
});
此外,我还尝试了以下代码:
In addition, I also tried the following code:
$http.get("http://localhost:4704/api/file/download").then(function (res) {
var anchor = angular.element('<a/>');
anchor.attr({
href: 'data:attachment/doc;charset=utf-8,',
target: '_blank',
download: 'test.doc'
})[0].click();
})
推荐答案
服务器代码显然正在发送二进制数据,以响应来自客户端的HTTP GET.在这种情况下,客户端需要将XHR设置为 responseType:arraybuffer
.
The server code is clearly sending binary data in response to an HTTP GET from the client. In that case the client needs to set the XHR to responseType: arraybuffer
.
示例HTML
<button ng-click="fetch()">Get file</button>
<a download="{{filename}}" xd-href="data">
<button>SaveAs {{filename}}</button>
</a>
HTML创建两个按钮.单击第一个按钮可从服务器获取文件.第二个按钮保存文件.
The HTML creates two buttons. Clicking the first button gets the file from the server. The second button saves the file.
xd-href
指令
xd-href
Directive
app.directive("xdHref", function() {
return function linkFn (scope, elem, attrs) {
scope.$watch(attrs.xdHref, function(newVal) {
newVal && elem.attr("href", newVal);
});
};
});
该指令监视由 xd-href
属性定义的scope属性,并将 href
属性设置为该scope属性的值.
The directive watches the scope property defined by the xd-href
attribute and sets the href
attribute to the value of that scope property.
控制器
var url = "http://localhost:4704/api/file/download/1";
$scope.fetch = function() {
$http.get(url, {responseType: "arraybuffer"})
.then (function (response) {
var disposition = response.headers("content-disposition");
var filename = disposition.match(/filename="(\w*.\w*)"/)[1];
$scope.filename = filename || "f.bin";
$scope.data = new Blob([response.data]);
}).catch(function (error) {
console.log(error);
throw error;
});
};
控制器使用XHR GET方法获取文件,从 Content-Disposition
标头中提取文件名,并从响应数据中创建blob.它将< a>
标记的 download
属性设置为文件名的值,并将 href
属性设置为blob的值.单击< a>
将使浏览器打开一个保存对话框.
The controller uses an XHR GET method to fetch the file, extracts the filename from the Content-Disposition
header, and creates a blob from the response data. It sets download
attribute of the <a>
tag to the value of the file name and the href
attribute to the value of the blob. Clicking on the <a>
will cause the browser to open a save dialog box.
这篇关于javascript从http响应保存文件(Web Api HttpResponseMessage)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!