Dart 和客户端文件处理(经授权) [英] Dart and Client Side File Handling (with authorization)

查看:18
本文介绍了Dart 和客户端文件处理(经授权)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

服务器端应用程序需要对文件下载链接进行授权.这意味着普通的 不再足以将足够的参数传递给服务器.

A server side application requires authorization on file download links. This means a normal <a ng-href="{{createLinkToFile()}}"> is no longer sufficient to get enough parameters passed to the server.

尝试使用程序化调用下载文件时,我将响应数据返回给 Dart 客户端应用程序.使用简单的 http GET:

When trying to use a programmatic call to the file download, I get the response data back to Dart client application. Using a simple http GET:

    var url = "http://example.com/file";
    headers.putIfAbsent("Authorization", () => "bearer " + token;
    _http.get(url: url, headers : headers);

GET 返回的 future 将保存数据,但我如何指示浏览器将其作为文件下载,而不是仅仅尝试将其保存在内存中?

The future returned by the GET will hold the data, but how do I instruct the browser to download it as a file, instead of just trying to keep it in memory?

或者有没有办法在普通链接中做到这一点?

Or is there a way to just do it in a normal link?

推荐答案

Seth 的代码确实解决了部分问题.为了使它更完整,我现在使用以下内容:

The code of Seth solves indeed part of the problem. To make it a bit more complete, I'm now using the following:

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.

A few things to notice. Instead of using the downloadLink.click(), a mouse event is constructed to ensure that it works on Firefox as well as on Safari and Chrome. Firefox seems not to handle the click() otherwise. Binding it to the DOM as is done in the code of Seth isn't necessary.

Internet Explorer 不理解下载属性,所以什么都不会发生,因此使用 window.open 至少让它在 IE 上工作(虽然不理想),它重定向到 self 以避免被弹出窗口击中向上拦截器.

Internet Explorer doesn't understand the download attribute, so nothing will happen, therefore a window.open is used to at least have it work (though not ideal) on IE, it's redirecting to self to avoid being hit by the pop up blocker.

有一些解决方案可以先将下载的结果转换为 Base64 并将其放入 data:mimetype href 中,使用 blob 这不是必需的.

There are solutions that convert the result download result to Base64 first and put it in a data:mimetype href, using the blob this isn't necessary.

在要下载的文件上设置文件名的一个好方法是通过内容处置标头,但此标头被标记为不安全,因此无法使用.现在在代码中设置了文件名.

A nice way to set the filename on the file to download would be through the content disposition header, but this header is marked as unsafe, so cannot be used. The filename is now set in the code.

另一个注意,注意使用了HttpRequest代替http.get(),HttpRequest允许你设置responseType,在这种情况下的 blob,可以转换为对象 url.

Another note, notice that a HttpRequest is used instead http.get(), The HttpRequest allows you to set the responseType, in this case blob, which can be transformed into a object url.

这篇关于Dart 和客户端文件处理(经授权)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆