从node.js

时间:2017-11-23 17:38:13

标签: node.js angular filesaver.js

我认为我非常接近我想做的事情。我在node.js中有以下api get方法,它从SQL Server数据库中检索文件varbinary(MAX)。它在插入之前从base64编码的字符串转换,因此从字符串中删除了内容类型信息。

的node.js

router.get('/getFile', (req, res) => {
    console.log("Calling getFile for file " + req.query.serialNumber + ".")
    var serialNumber = req.query.serialNumber;
    let request = new sql.Request(conn);
    request.query('SELECT FileName + \'.\' + FileExtension AS \'File\', FileType, ContentType, SerialNumber, Chart ' +
        'FROM dbo.ChangeFiles ' +
        'WHERE SerialNumber = ' + serialNumber)
        .then(function (recordset) {
            log("Successfully retrieved file " + recordset[0].SerialNumber + " from database.");
            log("Length of blob " + recordset[0].File + " is " + recordset[0].Chart.length)
            res.status(200);
            res.setHeader('Content-Type', recordset[0].ContentType);
            res.setHeader('Content-Disposition', 'attachment;filename=' + recordset[0].File);
            res.end(Buffer.from((recordset[0].Chart)));
        }).catch(function (err) {
            log(err);
            res.status(500).send("Issue querying database!");
        });
});

工作正常,但是在Angular中要做什么来检索它并提示为用户下载对我来说并不清楚,在线帮助/资源也没有那么多。以下是我目前在服务类中所拥有的内容。

fileDownload.service.ts

downloadFile(serialNumber: string): Observable<any> {
    return this.http.get(this.baseURL + '/getFile', { params: { serialNumber: serialNumber } })
    .map(this.extractFile);
}


private extractFile(response: Response) {
    const file = new Blob([response.blob]);
    FileSaver.saveAs(file);
    // const url = window.URL.createObjectURL(file);
    // window.open(url);
    return file;
}

正如你所看到的,我尝试了几种方法。 extractFile方法的注释部分根本不起作用,并且使用FileSaver.saveAs函数会生成未知类型的文件下载,因此从node.js发送的标头似乎不会影响文件本身。 / p>

有人能够建议如何在Angular中继续使用从node.js成功发送的内容,以便我可以成功下载该文件,无论其类型如何?

非常感谢。

2 个答案:

答案 0 :(得分:0)

更新您的代码以调用subscribe而不是map

答案 1 :(得分:0)

我完成了它的工作。我不得不重新编写api调用,以便它单独发送所有文件信息,以便可以将MIME类型和文件名分配给组件类中客户端的文件。出于某些原因,当我试图在api中这样做时,它不会起作用,所以这是我的工作。所以这对我有用。

node.js api

router.get('/getFile', (req, res) => {
    console.log("Calling getFile for file " + req.query.serialNumber + ".")
    var serialNumber = req.query.serialNumber;
    let request = new sql.Request(conn);
    request.query('SELECT FileName + \'.\' + FileExtension AS \'File\', FileType, ContentType, SerialNumber, Chart ' +
        'FROM dbo.ChangeFiles ' +
        'WHERE SerialNumber = ' + serialNumber)
        .then(function (recordset) {
            log("Successfully retrieved file " + recordset[0].SerialNumber + " from database.");
            log("Length of blob " + recordset[0].File + " is " + recordset[0].Chart.length)
            res.send(recordset[0]);
        }).catch(function (err) {
            log(err);
            res.status(500).send("Issue querying database!");
        });
});

组件类

  downloadFile(serialNumber: string): void {
    this.changeService.downloadFile(serialNumber).subscribe((res: any) => {
      const ab = new ArrayBuffer(res.Chart.data.length);
      const view = new Uint8Array(ab);
      for (let i = 0; i < res.Chart.data.length; i++) {
        view[i] = res.Chart.data[i];
      }
      const file = new Blob([ab], { type: res.ContentType });
      FileSaver.saveAs(file, res.File);
      console.log(res);
    });
  }

服务类

downloadFile(serialNumber: string): Observable<any> {
        return this.http.get(this.baseURL + '/getFile', { params: { serialNumber: serialNumber } })
        .map(this.extractFile);
    }

    private extractFile(response: Response) {
        // const file = new Blob([response.blob]);
        // FileSaver.saveAs(file);
        // const url = window.URL.createObjectURL(file);
        // window.open(url);
        const body = response.json();
        return body || {};
    }