Javascript 通过在Node.js和Express.js中请求前端数据来创建动态链接

Javascript 通过在Node.js和Express.js中请求前端数据来创建动态链接,javascript,node.js,express,Javascript,Node.js,Express,这对我来说有点难以解释,但我试图通过创建一个链接来缩短代码,而不是50个下载表单的链接。我将尝试使用我的代码更好地解释这一点 我有5个get请求,它们执行完全相同的操作,但下载不同的文件 router.get('/form1', function (req, res) { var file = __dirname + '/../public/forms/form1.pdf'; res.download(file); }); router.get('/form2', functi

这对我来说有点难以解释,但我试图通过创建一个链接来缩短代码,而不是50个下载表单的链接。我将尝试使用我的代码更好地解释这一点

我有5个get请求,它们执行完全相同的操作,但下载不同的文件

router.get('/form1', function (req, res) {
    var file = __dirname + '/../public/forms/form1.pdf';
    res.download(file);
});

router.get('/form2', function (req, res) {
    var file = __dirname + '/../public/forms/form2.pdf';
    res.download(file); 
});
etc...
我的前端链接是

<a href="/downloads/form1">FORM 1</a>
<a href="/downloads/form2">FORM 2</a>
etc...

但是我不知道如何获得表单名,或者是否可能。此响应假设您的路由位于
index.js

router.get('/form/:formName', (req, res, next) => {
  res.download(`${__dirname}/../public/forms/${req.params.formName}.pdf`);
});

<a href="/form/form2">FORM 2</a>
router.get('/form/:formName',(req,res,next)=>{
res.download(`${uu dirname}/./public/forms/${req.params.formName}.pdf`);
});

小心你的路线。我不知道你是否可以从一个目录开始,上一级,然后再下一级。

这里有更多的选项可以澄清:

  • 选项1:如果服务器上有一个目录结构相当易于管理的文件夹,只需使用express.static将物理文件夹映射到一个具有自动下载功能的虚拟文件夹:

    app.use('/download', express.static(path.join(__dirname, '/public/forms/')))
    
    这将导致前端带有href='/download/something.pdf'的任何链接都可以工作,只要该文件位于服务器上您映射的路径(即/public/forms)中

  • 选项2(上面David E基本上回答了这个问题):在您的原始代码中,如果您想为一个看起来像/download/form1、/download/form2的链接生成一个路径处理程序,它只是一个很小的修改:

    router.get('/download/:formNumber', function (req, res) {
        var file = __dirname + '/public/forms/' + req.params.formNumber + '.pdf';
        res.download(file);
    });
    
  • 选项3:您希望对文件的访问进行身份验证,并可能支持多个复杂的URL方案到单个处理程序,该处理程序可以查找适当的物理路径并发送文件:

    router.get('/download/:path[forms|images|files]/:formNumber1', fileRequestHandler);
    router.get('/public/downloadFolder2/:formNumber2', fileRequestHandler);
    router.get('/public/downloadFolder3/:formNumber3', fileRequestHandler);
    function fileRequestHandler(req, res) {
        // Check authentication here - example below from Passport
        if(!req.isAuthenticated()) 
            return res.status(401).send({err: 'Unauthorized'});
    
        // Check which form number is supplied and map to appropriate physical file
        if(req.params.formNumber1) {
            // in this example, req.params.path can be one of three allowed sample values - forms or images or files
            var file = __dirname + '/public/' + req.params.path + '/' + req.params.formNumber + '.pdf';
            res.download(file);
        } else if(req.params.formNumber2) {
            // etc.
        }
    }
    

注意:Ezra Chang关于路径有效性的观点很重要。

您的代码在我看来是正确的。。。您是否收到错误?@davino除了最后一部分之外,代码是正确的,因为前端没有“formName”请求。我不能只有5个不同的标签和formName,可以吗?。。。我有点困惑,我以为你要离开你的
应该带你去那个功能。。。如果您希望ui是动态的,那就另当别论了。你可能需要一种模板语言…@davino,你说得对。我只是想重构我的控制器功能。如果控制器是
router.get('/:formName',function(req,res),那么
将如何工作{…
?它怎么知道:formName是什么?这太完美了。我正在使用选项2,它可以像我想的那样工作。我只是不明白
req.params.formNumber
是如何工作的。它怎么知道从
中选择参数而不是其他东西?我将查看文档以尝试理解这个赌注ter但是你的回答涵盖了我目前需要知道的所有内容。注意formNumber前面的冒号(:)?这就是Express router将URL的后半部分视为变量的原因。因此使用/download/:variableName将匹配任何以单词
download
开头的传入请求(这是静态匹配),后面跟着一个
/
,然后是任何其他单词。只要你不给路由器太相似的东西而混淆它,它就可以设置一个路由表来匹配传入的请求。谢谢。我现在完全理解了它,这为我打开了更多的选择,我不必重复很多代码。
router.get('/download/:path[forms|images|files]/:formNumber1', fileRequestHandler);
router.get('/public/downloadFolder2/:formNumber2', fileRequestHandler);
router.get('/public/downloadFolder3/:formNumber3', fileRequestHandler);
function fileRequestHandler(req, res) {
    // Check authentication here - example below from Passport
    if(!req.isAuthenticated()) 
        return res.status(401).send({err: 'Unauthorized'});

    // Check which form number is supplied and map to appropriate physical file
    if(req.params.formNumber1) {
        // in this example, req.params.path can be one of three allowed sample values - forms or images or files
        var file = __dirname + '/public/' + req.params.path + '/' + req.params.formNumber + '.pdf';
        res.download(file);
    } else if(req.params.formNumber2) {
        // etc.
    }
}