服务器端应用程序需要文件下载链接的授权。这意味着正常的<a ng-href="{{createLinkToFile()}}">
不再足以将足够的参数传递给服务器。
当尝试使用程序调用文件下载时,我将响应数据返回给Dart客户端应用程序。使用简单的http GET:
var url = "http://example.com/file";
headers.putIfAbsent("Authorization", () => "bearer " + token;
_http.get(url: url, headers : headers);
GET返回的未来将保存数据,但是如何指示浏览器将其作为文件下载,而不是仅仅将其保存在内存中?
或者有没有办法在普通链接中执行此操作?
答案 0 :(得分:1)
从Using Dart to Download a PNG File (Binary File) and displaying it not working中显示的服务器下载数据后,您可以创建http://blog.butlermatt.me/2014/03/dynamically-generating-download-files/所示的下载链接
import 'dart:html';
void main() {
List body = [ 'Some test data ...\n'];
// Create a new blob from the data.
Blob blob = new Blob(body, 'text/plain', 'native');
// Create a data:url which points to that data.
String url = Url.createObjectUrlFromBlob(blob);
// Create a link to navigate to that data and download it.
AnchorElement link = new AnchorElement()
..href = url
..download = 'random_file.txt'
..text = 'Download Now!';
// Insert the link into the DOM.
var p = querySelector('#text');
p.append(link);
}
答案 1 :(得分:0)
Seth的代码确实解决了问题的一部分。为了使它更完整,我现在使用以下内容:
void doPdfFileRequest(String url) {
var request = new HttpRequest();
request.open('GET', url);
request.responseType = "blob";
request.withCredentials = false;
request.setRequestHeader("Accept", _httpAcceptHeader);
request.setRequestHeader("Authorization", "bearer " + token);
request.onReadyStateChange
.listen((r) => onData(request, "filename.pdf"));
request.send();
}
void onData(HttpRequest request, String filename) {
if (request.readyState == HttpRequest.DONE && request.status == 200) {
if (!isIE()) {
var contentType = request.getResponseHeader("content-type");
AnchorElement downloadLink = new AnchorElement(
href: Url.createObjectUrlFromBlob(request.response));
downloadLink.rel = contentType;
downloadLink.download = filename;
var event = new MouseEvent("click", view: window, cancelable: false);
downloadLink.dispatchEvent(event);
} else {
var href = Url.createObjectUrlFromBlob(request.response);
window.open(href, "_self");
}
}
}
要注意的一些事情。不使用downloadLink.click()
,而是构建鼠标事件以确保它可以在Firefox以及Safari和Chrome上运行。 Firefox似乎不会处理click()。如在Seth的代码中所做的那样将它绑定到DOM是不必要的。
Internet Explorer不了解下载属性,因此不会发生任何事情,因此使用window.open至少使其在IE上工作(虽然不理想),它会重定向到自己避免被弹出窗口拦截器击中。
有些解决方案首先将结果下载结果转换为Base64并将其放在data:mimetype
href中,使用blob这不是必需的。
在要下载的文件上设置文件名的好方法是通过内容处置标头,但此标头被标记为不安全,因此无法使用。文件名现在在代码中设置。
另一个注释,请注意使用HttpRequest
代替http.get()
,HttpRequest允许您设置responseType,在本例中为blob,可以转换为对象网址。