打开下载链接In TypeScript(Angular)

时间:2016-04-12 08:49:13

标签: angular

我的问题很简单。我用Angular构建了this interface。当我点击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); =>中为我提供了一个很好的网址,它可以很好地下载文件:)

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

修改1:

搬家后 -

Dashboard.components.ts:

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

show download链接中调用downloadFile,就像之前一样。

在_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它完美运作。

2 个答案:

答案 0 :(得分:2)

一种方法是通过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 ]
})

有关详细信息,请参阅此答案:

答案 1 :(得分:0)

简单的解决方案是&#34; getDownloadLink&#34;返回中间链接,将用户重定向到您想要的实际链接。

User

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