简单的动态文件下载

时间:2019-05-30 08:53:24

标签: node.js reactjs express

我明白了为什么我不能有一个react按钮来启动文件下载(不被黑客攻击)并且我不想被黑客攻击。

我想要的是一个非常简单的解决方案,其中...

  • 我按下一个在后端创建文件的按钮
  • 前端显示一个链接
  • 我单击此按钮,浏览器提示我将文件保存在何处。

单击按钮将生成链接。单击链接只会使页面重新加载浏览器中的URL。

此外:我用其他技术做了无数次。为什么nodejs / react world使得这次荣幸的,简单的任务变成不可能?

我尝试并引导我朝着这个方向的2条链接...

server.js

const bodyParser = require('body-parser');
var express = require('express');
var PdfHandler = require('./pdfHandler.js');

const pdfHandler = new PdfHandler();
const app = express();
const port = process.env.PORT || 3001;

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.listen(port, () =>
    console.log('Express server is running on localhost:3001')
);

app.post('/api/createpdfinvoice', (req, res) => {
    pdfHandler.handleCreate(req, res);
})

app.get('/api/downloadinvoice/:filename', (req, res) => {
    pdfHandler.handleDownload(req, res, filename);
})

pdfhandler.js

const fs = require('fs');
const Invoice = require('./Invoice.js');
var path = require('path');

class PdfHandler {

    constructor() {
        this.invoicesDir = "./invoices";
        if (!fs.existsSync(this.invoicesDir)){
            fs.mkdirSync(this.invoicesDir);
        }
    }

    handleCreate(req, res) {
        console.log("Creating invoice...");
        let invoice = new Invoice(this.invoicesDir, req.body);
        invoice.createPdf();
        res.setHeader('Content-Type', 'application/json');
        res.send(JSON.stringify( {"file": invoice.fileName} ));
    }

    handleDownload(req, res, filename) {
        res.download(path.join(this.invoicesDir, filename), filename);
    }
}

module.exports = PdfHandler;

app.js

import React, { Component } from 'react';
import './App.css';

export default class App extends Component {

    constructor() {
        super();

        this.state = {
            filename: null
        }

        this.createPdf_onClick = this.createPdf_onClick.bind(this);
    }

    createDownloadDiv() {
        return (
            <div>
                <a href={"/api/downloadinvoice/" + this.state.filename}>download invoice</a>
            </div>
        )
    }

    createPdf_onClick() {

        console.log("Creating PDF...");
        this.setState({ type: "loading" });

        fetch(`/api/createpdfinvoice`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    "company": "ERA",
                    "date": "1999-07-02"})})
            .then(response => response.json())
            .then(data => {
                this.setState({
                    type: "downloadpdf",
                    filename: data.file
                });
            });
    }

    render() {
        let downloadDiv;
        if (this.state.filename) {
            downloadDiv = this.createDownloadDiv();
        }

        return (
            <div className="App">
                <button onClick={this.createPdf_onClick}>create PDF</button>
                {downloadDiv}
            </div>
        );
    }
}

是的,PDF确实存在。

0 个答案:

没有答案