Nodejs express的路由规则问问大家

Nodejs express的路由规则问问大家

我希望photos/upload/{md5(title+username+uploaded)}{width}{height}.{jpg/png/gif}获取一张图片,但这个URL不是图片的的真实地址,因为我想做个防盗链,而且方便获取的图片API,express支持这一的规则吗?

3 回复

当然可以!Express.js 提供了强大的路由机制来处理这种复杂的 URL 结构。你可以使用参数匹配、正则表达式以及中间件来实现你提到的需求。

示例代码

const express = require('express');
const app = express();

// 假设你有一个函数来生成图片的真实路径
function generateImagePath(md5Hash, width, height, extension) {
    return `/path/to/images/${md5Hash}-${width}x${height}.${extension}`;
}

// 定义一个中间件来处理防盗链
app.use((req, res, next) => {
    // 这里可以添加你的防盗链逻辑,例如检查 Referer 头
    const referer = req.headers.referer;
    if (referer && referer.includes('yourdomain.com')) {
        next();
    } else {
        res.status(403).send('Forbidden');
    }
});

// 定义路由规则
app.get('/photos/upload/:md5hash_:width_:height.(:ext)', (req, res) => {
    const { md5hash, width, height, ext } = req.params;

    // 验证扩展名是否合法
    const validExtensions = ['jpg', 'png', 'gif'];
    if (!validExtensions.includes(ext)) {
        return res.status(400).send('Invalid file format');
    }

    // 生成图片的真实路径
    const imagePath = generateImagePath(md5hash, width, height, ext);

    // 返回图片或进行其他处理
    res.send(`The image path is: ${imagePath}`);
});

// 启动服务器
app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释

  1. 路由定义:

    • 使用 app.get 方法定义了一个 GET 请求的路由。
    • :md5hash, :width, :height:ext 是动态参数,分别匹配 URL 中的 md5hash, width, heightext 部分。
  2. 中间件:

    • 在处理请求之前,我们定义了一个中间件来检查 Referer 头,确保请求来自指定的域名(这里假设为 yourdomain.com)。如果 Referer 头不包含该域名,则返回 403 Forbidden 状态码。
  3. 验证扩展名:

    • 我们通过检查 req.params.ext 是否在有效扩展名列表中来验证文件格式。如果不合法,则返回 400 Bad Request 状态码。
  4. 生成真实路径:

    • 使用 generateImagePath 函数根据传入的参数生成图片的真实路径,并返回给客户端。

这样,你就可以通过访问类似 /photos/upload/abcdef12345_800_600.jpg 的 URL 来获取图片,同时实现了防盗链功能。


谢谢了

Express 支持通过动态路由参数来实现你所描述的需求。你可以使用冒号 (:) 来定义动态路由段,然后通过 req.params 对象访问这些参数。

以下是一个示例代码,展示如何设置这样的路由:

const express = require('express');
const app = express();

app.get('/photos/upload/:md5TitleWidthHeight.:extension', (req, res) => {
    const { md5TitleWidthHeight, extension } = req.params;

    // 解析出 title, username 和 uploaded 等信息
    const [title, username, uploaded] = decodeURIComponent(md5TitleWidthHeight).split('+');

    // 做一些逻辑处理,例如验证用户权限、获取图片等
    // 这里可以添加你的业务逻辑

    // 返回图片或者错误信息
    res.send(`处理 ${title}, ${username}, ${uploaded} 的图片,格式为 .${extension}`);
});

// 启动服务器
app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释:

  1. 路由定义/photos/upload/:md5TitleWidthHeight.:extension

    • :md5TitleWidthHeight 是一个动态路由参数,表示 md5(title+username+uploaded) 部分。
    • .extension 表示文件的扩展名(如 jpg, png, gif)。
  2. 请求处理:在处理函数中,通过 req.params.md5TitleWidthHeight 获取 md5(title+username+uploaded) 部分,并通过 req.params.extension 获取文件扩展名。

  3. 解码与分割:使用 decodeURIComponentmd5TitleWidthHeight 进行解码,并通过 split('+') 分割字符串以获取 title, usernameuploaded

  4. 业务逻辑:这里你可以根据需要添加更多的业务逻辑,例如权限验证、图片读取等。

通过这种方式,你可以实现防盗链的功能,同时方便地管理和调用图片 API。

回到顶部