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

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

问题描述

服务器端应用程序需要文件下载链接的授权.这意味着普通的<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返回的将来将保存数据,但是我如何指示浏览器将其下载为文件,而不是仅仅尝试将其保存在内存中?

还是有一种方法可以在普通链接中做到这一点?

解决方案

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");
      }
   }
}

一些注意事项.构造鼠标事件以确保它可以在Firefox以及Safari和Chrome上运行,而不是使用downloadLink.click(). Firefox似乎不会处理click().不需要像Seth的代码那样将其绑定到DOM.

Internet Explorer无法理解下载属性,因此不会发生任何事情,因此使用window.open至少可以使其在IE上正常工作(尽管不理想),它会重定向到self以避免被弹出窗口击中拦截器.

有些解决方案可以先将结果下载结果转换为Base64,然后将其放入data:mimetype href中,而不必使用blob.

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

另一个说明,请注意,使用HttpRequest代替http.get(),HttpRequest允许您设置responseType,在这种情况下为blob,可以将其转换为对象url./p>

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.

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);

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?

解决方案

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");
      }
   }
}

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 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.

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.

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天全站免登陆