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.