【问题标题】:Open Download link In TypeScript (Angular)在 TypeScript (Angular) 中打开下载链接
【发布时间】:2016-04-12 08:49:12
【问题描述】:

我的问题很简单。我有 this interface 用 Angular 构建的。当我点击 1 时,它会打开弹出窗口,然后当我点击 2 时,它会调用一个函数:

showDownloadLink(ev, name) {
    let config = new MdDialogConfig()
        .textContent('<a href="http://www.google.fr">lol</a>')
        .clickOutsideToClose(false)
        .title('Would you like to delete your debt?')
        .ariaLabel('Lucky day')
        .ok('Please do it!')
        .cancel('Sounds like a scam')
        .targetEvent(ev);
    this.dialog.open(MdDialogBasic, this.element, config)
        .then((ref: MdDialogRef) => {
            ref.whenClosed.then((result) => {
                if (result) {
                    var url = this._Service.getDownloadLink(name);
                    console.log(url);
                    //window.open(url,'Download');
                    //this.downloadURI(url );
                }
                else {
                    this.status = 'You decided to keep your debt.';
                }
            })
        });
}

downloadURI(uri) {
    var link = document.createElement("a");
    link.href = uri;
    link.click();
}

使用的模块是ng2-material,带有“确认对话框”按钮。

当我点击控制台中显示的链接时,var url 在控制台console.log(url); =&gt; 中为我提供了一个很好的 url,它可以很好地下载文件:)

问题是代码中没有触发下载。

编辑 1:

移动一些东西后-

Dashboard.components.ts:

downloadFile(url,file) {
    this._Service.getDownloadFile(url,file);
}

downloadFile 像以前一样在show download 链接中调用。

在_service.ts中:

import {Injectable} from "angular2/core";
import {S3Object} from "./s3object";
import {Observable} from "rxjs/Observable";
import {Http, Headers, Response} from "angular2/http";
import "rxjs/Rx";
import {CredService} from "./cred.service";
//mettre les parenthèses !!
@Injectable()
export class Service {

    private serviceUrl = 'url';
    private token;
    private headers = new Headers();
    private credS;

    constructor(private http:Http, private cred:CredService) {
        this.credS = cred;
        this.token = cred.getToken();
        this.headers.append('Authorization', 'bearer ' + this.token);
        this.headers.append('Content-Type', 'application/json');
    }

    getDownloadLink(path:string){
        var opUrl = 'download.json?objectKey='+path;
        var urlRes = "";
        this.http.get(
            this.serviceUrl + opUrl,
            { headers: this.headers }
        )
            .map(res => res.text())
            .subscribe(
                data => urlRes = data,
                err => console.log(err),
                () => console.log(urlRes)
            );

        //console.log(urlRes);
        return urlRes;
    }

    getDownloadFile(url:string, file:string) {
        this.http.get(url).subscribe(
            (response) => {
                var blob = new Blob([response._body], {type: "application/text"});
                var filename = file;
                saveAs(blob, filename);
            });
    } 
}

还有一个 customBrowserXhr.ts 文件:

import {Injectable} from 'angular2/core';
import {BrowserXhr} from 'angular2/http';

@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
    constructor() {}
    build(): any {
        let xhr = super.build();
        xhr.responseType = "blob";
        console.log("it's cool bro ! ");
        return <any>(xhr);
    }
}

编辑2:

我的控制台函数执行日志(我在代码中用URL替换了正确的url)

test url ddl before : "URL/Desert.jpg?serieofparams"
test name ddl before : Desert.jpg

功能:

downloadFile(url,file) {
    console.log('test url ddl before : ' + url);
    console.log('test name ddl before : ' + file);
    this.http.get(url).subscribe(
        (response) => {
            var blob = new Blob([response._body], {type: "image/jpeg"});
            var filename = file;
            saveAs(blob, filename);
        });
}

但是我收到了这个错误:

Failed to load resource: the server responded with a status of 404 (Introuvable) http://localhost:8080/context/%22URL/Desert.jpg?serieofparams%22
angular2.dev.js:23740 EXCEPTION: [object Object]

有人知道是什么原因造成的吗? 路由模块有可能这样做吗? 在 this Plunkr 上,它运行良好。

【问题讨论】:

  • 我怎样才能在下载中允许多种类型.. 比如 pdf、lpg、png {type: "image/jpeg"});

标签: angular


【解决方案1】:

一种方法是通过 AJAX 请求加载图像,然后利用 FileSaver 库打开下载对话框。

这是一个示例。您需要扩展BrowserXhr 类来设置响应类型。

@Injectable()
export class CustomBrowserXhr extends BrowserXhr {
  constructor() {}
  build(): any {
    let xhr = super.build();
    xhr.responseType = "blob";
    return <any>(xhr);
  }
}

那么你就可以利用这个类来执行获取图片内容的请求了:

@Component({
  selector: 'download',
  template: `
    <div (click)="downloadFile() ">Download</div>
  `,
  providers: [
    provide(CustomBrowserXhr, 
      { useClass: CustomBrowserXhr }
  ]
})
export class DownloadComponent {
  @Input()
  filename:string;

  constructor(private http:Http) {
  }

  downloadFile() {
    this.http.get(
      'https://mapapi.apispark.net/v1/images/'+this.filename).subscribe(
        (response) => {
          var mediaType = 'application/pdf';
          var blob = new Blob([response._body], {type: mediaType});
          var filename = 'test.pdf';
          saveAs(blob, filename);
        });
    }
}

这个覆盖(设置响应类型)只适用于这个组件(不要忘记在引导您的应用程序时删除相应的提供),因为我在组件的providers 属性中设置了提供程序。下载组件可以这样使用:

@Component({
  selector: 'somecomponent',
  template: `
    <download filename="'Granizo.pdf'"></download>
  `
  , directives: [ DownloadComponent ]
})

查看此答案了解更多详情:

【讨论】:

  • 我正在研究它,即使我不太了解这个可能的解决方案。
  • 其实是通过AJAX请求加载图片内容的。 Angular2 的问题在于它现在只支持文本内容。因此,您需要进行一些调整以使其成为可能;-) 我更新了答案以提供更多详细信息...
  • 在我不知道文件类型的情况下它也可以工作吗?它在屏幕上是 png,但它可以是 pdf 或其他类型的文件
  • 可以,但是需要从响应的Content-Type标头中提取类型...
  • Okey n,我使用了您的解决方案,并且下载开始 BUUUUUT 每个文件都已损坏:/
【解决方案2】:

简单的解决方案是“getDownloadLink”返回中间链接,该链接会将用户重定向到您想要的实际链接。

var url = this._Service.getDownloadLink(name);
console.log(url);
window.location = url;

请注意,在实际下载链接中,您需要从服务器端设置适当的内容处置标头。

【讨论】:

  • 该解决方案不起作用。在我的情况下,只使页面在同一位置刷新而不启动任何下载
猜你喜欢
  • 1970-01-01
  • 2011-08-27
  • 1970-01-01
  • 2011-01-03
  • 2021-07-03
  • 2018-12-06
  • 1970-01-01
  • 2022-06-27
  • 2013-02-03
相关资源
最近更新 更多