【node】使用express+gitee搭建图床,并解决防盗链问题

首先创建一个gitee的项目,详细步骤我就不一一说明

注解:大家记得将这个项目开源,还有记得获取自己的私钥,私钥操作如下:

node依赖下载:

"axios": "cors": "express": "multer": "nodemon":

app.js代码:

javascript 复制代码
const express = require('express');
const multer = require('multer');
const axios = require('axios');
const cors = require('cors');

const app = express();
app.use(cors());
const port = 3000;

// 设置 Multer 中间件来处理文件上传
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });

// 处理静态文件
app.use(express.static('public'));

// 显示图床上的所有图片
app.get('/', async (req, res) => {
  try {
    const response = await axios.get('https://gitee.com/api/v5/repos/zsd12138/drawing-bed/contents/image?access_token=xxxxxxxxxx');
    const images = response.data.map(item => item.download_url);
    res.send(`
      <div style="display: flex;">
        ${images.map(image =>
      `<div style="display: flex;
          flex-direction: column;
          align-items: center;"><img src="${image}" style="height: 200px;margin-right: 20px;"> <span  style="cursor: pointer;">点击图片删除</span></div>`
    ).join('')}
      </div>
    `);
  } catch (error) {
    console.error(error);
    res.status(500).send('无法获取图片列表');
  }
});

// 上传图片到图床
app.post('/upload', upload.single('image'), async (req, res) => {
  try {
    const { buffer, originalname } = req.file;
    const encodedFile = buffer.toString('base64');
    const response = await axios.post('https://gitee.com/api/v5/repos/zsd12138/drawing-bed/contents/image/' + originalname, {
      access_token: "xxxxxxxxxx",
      branch: 'master',
      content: encodedFile,
      message: `上传图片 ${originalname}`,
    });
    res.status(200).send(response.data);
  } catch (error) {
    // console.error(error);
    res.status(500).send('无法上传图片');
  }
});

// 删除图床上的图片
app.get('/delete/:filename', async (req, res) => {
  const filename = req.params.filename;
  try {
    // 获取sha
    const shaDate = await axios.get('https://gitee.com/api/v5/repos/zsd12138/drawing-bed/contents/image/' + filename + '?access_token=xxxxxxxxxxx');
    // console.log(shaDate.data.sha)
    // 删除操作
    const response = await axios.delete('https://gitee.com/api/v5/repos/zsd12138/drawing-bed/contents/image/' + filename, {
      params: {
        access_token: "xxxxxxxxxxxxx",
        branch: 'master',
        message: `删除图片 ${filename}`,
        sha: shaDate.data.sha
      },
    });
    res.status(200).send(`已删除${filename}`);
  } catch (error) {
    console.error(error.data);
    res.status(500).send(`无法删除图片 ${filename}`);
  }
});

// 启动服务器
app.listen(port, () => {
  console.log(`服务器正在运行,访问 http://localhost:${port}`);
});

access_token替换成自己的私人令牌

index.html

html 复制代码
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>图床</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>

<body>
    <h2>上传图片</h2>
    <form id="uploadForm">
        <input type="file" id="fileInput">
        <button type="submit">上传图片</button>
    </form>

    <h2>所有图片</h2>
    <div id="images"></div>

    <script>
        $(function () {
            // 删除图片
            $('#images').on('click', 'img', function () {
                const imageUrl = $(this).attr('src');
                const filename = imageUrl.substring(imageUrl.lastIndexOf('/') + 1);
                if (confirm(`确定删除 "${filename}"?`)) {
                    $.ajax({
                        url: 'http://172.21.2.52:3000/delete/' + filename,
                        type: 'get',
                        success: () => {
                            // $(this) 表示当前被选中的元素,.remove() 用于从 DOM 中移除元素。
                            // $(this).remove();
                            getIamge()
                        },
                        error: () => {
                            alert('Delete failed.');
                        }
                    });
                }
            });
        })
        var getIamge = function () {
            // 获取图床上的所有图片
            $.ajax({
                url: 'http://172.21.2.52:3000/',
                method: 'GET',
                success: function (html) {
                    $('#images').html(html);
                },
                error: function () {
                    console.error('无法获取图片列表');
                }
            });
        }
        getIamge()
        // 上传图片到图床
        $('#uploadForm').submit(function (event) {
            event.preventDefault(); // 阻止表单的默认提交行为

            const formData = new FormData();
            formData.append('image', $('#fileInput')[0].files[0]);
            console.log($('#fileInput')[0].files[0])
            $.ajax({
                url: 'http://172.21.2.52:3000/upload',
                type: 'POST',
                data: formData,
                processData: false,
                contentType: false,
                success: function (result) {
                    getIamge()
                    console.log(result);
                },
                error: function (error) {
                    console.error(error);
                }
            });
        })

    </script>
</body>

</html>

运行效果:全部都302 重定向了,这就是做了防盗链,下面来讲讲防盗链

防盗链

要实现防盗链,就需要知道图片的请求是从哪里发出的。可以实现这一功能的有请求头中的originrefererorigin只有在XHR请求中才会带上,所以图片资源只能借助referer

通过判断请求的referer,如果请求来源不是本站就返回302

一个完整的流程:

  • 首先请求正常的图片,但是没有返回200,而是302重定向,其中响应头中的location就是要重定向去向的地址;
  • 接着浏览器会自动请求这个location,并用这个返回结果代替第一次请求的返回内容

如何破解防盗链

想让gitee不知道我在盗用,就不能让他发现请求的来源是第三方,只要把referer藏起来就好

代码实现:

html 复制代码
//增加到html的头部
<meta name="referrer" content="no-referrer" />

注解:
<meta name="referrer" content="no-referrer" /> 指定了 "no-referrer" 的内容,意味着浏览器在发送请求时不会包含任何引用来源信息。换句话说,当用户从当前网页跳转到其他页面时,新页面接收到的请求中将不包含这个跳转前的页面地址

最后效果图

增加meta头部配置后

附上gitee请求文档:

Gitee API 文档

相关推荐
jonyleek3 天前
JVS开源框架:工作流引擎代理中心的设计挑战与实现方案
java·gitee·开源·github·软件需求
Sheljoee.4 天前
【GitHub】基础入门步骤
开发语言·人工智能·python·单片机·gitee·github·嵌入式实时数据库
胡西风_foxww4 天前
nodejs爬虫系统
爬虫·nodejs·node·系统·express·request·cheerio
影阴5 天前
如何将本地项目上传至Gitee仓库(详细教程)
gitee
loveLifeLoveCoding6 天前
gitee 使用 webhoot 触发 Jenkins 自动构建
运维·gitee·jenkins
子蛟7 天前
Android Studio 安装过程
android·gitee·android studio
南鸢1.07 天前
IntelliJ IDEA 中上传项目到 Gitee 的完整指南
java·git·gitee·idea
松果猿8 天前
场地污染在线计算可视化平台,获得易智瑞GIS开发竞赛C组优胜奖,内附易智瑞GIS开发竞赛与全国大学生测绘学科创新创业智能大赛提交材料。
vue·express
一个很帅的帅哥8 天前
Mac在Typora配置PicGo图床,以github为例
macos·gitee·github·typora·mac·图床
謬熙8 天前
GitHub、Gitee、GitLab介绍
gitee·gitlab·github