Dart 和客户端文件处理(授权)
Dart and Client Side File Handling (with authorization)
服务器端应用程序需要文件下载授权 links。这意味着普通的 <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 返回的未来将保存数据,但我如何指示浏览器将其下载为文件,而不是仅仅试图将其保存在内存中?
或者有没有办法以正常的方式做到这一点 link?
从服务器下载数据后 Using Dart to Download a PNG File (Binary File) and displaying it not working you can create a download link like shown at 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);
}
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,这不是必需的。
在要下载的文件上设置文件名的一个好方法是通过内容配置 header,但是这个 header 被标记为不安全,因此不能使用。文件名现在已在代码中设置。
另一个注意事项,请注意使用 HttpRequest
代替 http.get()
,HttpRequest 允许您设置 responseType,在本例中为 blob,它可以转化为objecturl.
服务器端应用程序需要文件下载授权 links。这意味着普通的 <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 返回的未来将保存数据,但我如何指示浏览器将其下载为文件,而不是仅仅试图将其保存在内存中?
或者有没有办法以正常的方式做到这一点 link?
从服务器下载数据后 Using Dart to Download a PNG File (Binary File) and displaying it not working you can create a download link like shown at 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);
}
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,这不是必需的。
在要下载的文件上设置文件名的一个好方法是通过内容配置 header,但是这个 header 被标记为不安全,因此不能使用。文件名现在已在代码中设置。
另一个注意事项,请注意使用 HttpRequest
代替 http.get()
,HttpRequest 允许您设置 responseType,在本例中为 blob,它可以转化为objecturl.