玩:搭建自己的图床服务器。借助免费一小时服务器,来开发一个简单图床在线网站。

曾几何时,我还是一个小小白(现在已经进步了------是小白了),一直想试试搭建一个自己的在线图床网站来玩一玩,但是又不想花钱买服务器(毕竟新用户资格的优惠是最大的,不能随便浪费),于是一番查找发现阿里云提供了免费服务器供学生学习。我现在还记得当初成功搭建线上图床时有多兴奋!

(最近整理笔记时才发现)当时专门写了一篇笔记来记录整个过程,于是专门分享出来。

准备免费服务器,并连接到云端

进入 场景体验------搭建Node.js编程环境




复制公网 IP 和密码



打开本机 powershell 运行下面命令。推荐使用 window ternimal(点击查看之前的文章,介绍了如何安装 wt

bash 复制代码
ssh [email protected]

配置 node 环境

下载 node 12 版本。(高版本需要额外的处理,这里为了方便,直接使用 12 版本)

bash 复制代码
wget https://nodejs.org/download/release/v12.22.12/node-v12.22.12-linux-x64.tar.gz

解压安装。(使用 -xvf 则可以输出解压信息)

bash 复制代码
tar -xf node-v12.22.12-linux-x64.tar.gz

将解压后的内容移动到另外位置。

bash 复制代码
mv node-v12.22.12-linux-x64 /usr/local/node12

也可以使用 tar -xf node-v12.22.12-linux-x64.tar.gz -C /usr/local/node12 一步到位

配置环境变量

bash 复制代码
echo "export PATH=$PATH:/usr/local/node12/bin" >> /etc/profile

刷新配置文件以便生效

bash 复制代码
source /etc/profile

测试环境变量是否成功配置

bash 复制代码
node -v
npm -v

搭建简易图床项目

  1. 创建一个文件夹

    bash 复制代码
    mkdir -p /usr/www/simple-gallery && cd "$_"
  2. 初始化环境

    bash 复制代码
    npm init -y
  3. 使用淘宝 npm 镜像源,不然网络太慢难以下载

    bash 复制代码
    npm config set registry https://registry.npmmirror.com
  4. 安装 express 搭建服务器,安装 multer 上传文件,安装 nodemon 热更新(如果你运行顺利的话,并不需要这个)

    bash 复制代码
    npm i --save express multer nodemon

搭建好环境后,你们可以选择自己敲代码,我这里为了方便,直接提供了案例代码。一共只有两个文件 index.jsindex.html

index.html 内容

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>简易在线图床</title>

    <style>
        #preview-box {
            display: flex;
            flex-wrap: wrap;
        }

        img {
            max-width: 200px;
            margin: 20px;
            border-radius: 10px;
            box-shadow: 0 0 5px #666;
        }

        button {
            margin: 20px;
            width: 80px;
            height: 40px;
            border-radius: 10px;
        }
    </style>
</head>

<body>

    <form action="upload" method="post" enctype="multipart/form-data">
        <button type="submit">上传</button>
        <input type="file" name="files" required multiple accept="image/*">
    </form>

    <div id="preview-box"> </div>

    <script>
        const previewBox = document.getElementById('preview-box')
        const form = document.querySelector('form')

        form.onsubmit = formSubmit

        function formSubmit(e) {
            try {
                /** @type {HTMLFormElement} */
                const form = e.currentTarget
                const req = new Request(form.action, {
                    method: form.method,
                    body: new FormData(form)
                })

                fetch(req).then(res => {
                    if (!res.ok) {
                        throw new Error(`HTTP error! Status: ${res.status}`);
                    }
                    return res.json()
                }).then((data) => {
                    data.forEach(url => {
                        previewImg(url)
                    });
                })
            } catch (error) {

            }
            return false
        }

        function previewImg(path) {
            const a = document.createElement('a')
            a.innerHTML = `<img src=${path} alt="预览的图片" />`
            a.href = path
            a.target = '_blank'
            previewBox.prepend(a)
        }

    </script>

</body>

</html>

index.js 内容

js 复制代码
const express = require('express')
const multer = require('multer')
const fs = require('fs')
const path = require('path')
//const { randomUUID } = require('crypto') node 版本太低不支持

const app = express()
const upload = multer()

const PORT = 80 // 本地运行时推荐修改此端口
const IMG_RELATIVE_PATH = 'img'
const __IMG_PATH = path.resolve(IMG_RELATIVE_PATH)
const __ROOT_PATH = path.resolve('./index.html')


initFolder(__IMG_PATH)
app.use(express.json())

app.get('/', (req, res) => {
    res.sendFile(__ROOT_PATH)
})

app.get(`/${IMG_RELATIVE_PATH}/:img`, (req, res) => {
    res.sendFile(`${__IMG_PATH}/${req.params.img}`)
})

app.post('/upload', upload.any(), (req, res) => {
    const imgs = []
    req.files.forEach(file => {
        const filename = generateName(file.mimetype)
        const filepath = path.join(__IMG_PATH, filename)
        fs.writeFileSync(filepath, file.buffer)
        imgs.push(`/${IMG_RELATIVE_PATH}/${filename}`)
    })

    res.send(imgs)
})

app.use((err, req, res, next) => {
    res.status(500).send('Something broke!')
    console.log(err);
})


app.listen(PORT, () => {
  console.log(`Example app listening on port ${PORT}`)
})


// ------------------

function initFolder(img_path) {
    if (!fs.existsSync(img_path)) {
        fs.mkdirSync(img_path)
    }
}

// 替代 crypto.randomUUID
function randomUUID() {
    return Math.random().toString().substring(2)
}

function generateName(minetype) {

    // const ext = minetype.split('/').at(-1) 不支持 split 函数
    const ext = minetype.substring(6) // 由于我们确信时 image/xxx 所以直接通过字符串定位获取后缀名
    return randomUUID() + (
        ext ? `.${ext}` : ''
    )
}

上传文件内容

为了方便,我们不借助 xftp 等工具上传文件,而是直接将文件内容发送到服务器。新建终端,执行下面命令

bash 复制代码
get-content "D:\draft\all-code-tmp\index.html" | ssh [email protected] "cat > /usr/www/simple-gallery/index.html"
# 路径需改成你自己的本机 index.html 路径,IP 也要改成你自己的 IP

get-content "D:\draft\all-code-tmp\index.js" | ssh [email protected] "cat > /usr/www/simple-gallery/index.js"
# 路径需改成你自己的本机 index.js 路径,IP 也要改成你自己的 IP

然后回到服务器终端,查看文件是否成功上传

bash 复制代码
ls -al

然后启动项目

bash 复制代码
node_modules/.bin/nodemon index.js
# 这里就不在 package.json 的 scrip 中配置命令 nodemon index.js 了

# 或者

node index.js &
# & 符号表示后台运行,这是可选的。

测试图床功能

打开公网 ip (由于是阿里云提供的用于学习的服务器,所有不需要考虑防火墙等内容)




可以看到,虽然只给了免费一小时,但这是完全够用的(而且在这过程中我还遇到了一些 bug 耽搁了一些时间)

如果你看到这里,那你还不赶紧试试😁。这篇文章可能具有时效性,因为旧笔记中的很多内容就是过时了。

我是怎么找到 node12 版本链接的

如果有人是跟着实验手册走的,那么可能会发现实验手册中的 node 版本链接是无法下载的,原因是淘宝已经换源了。



有些初学者可能不知道官网的 node 链接应该如何找,这里我就专门提一下:

进入 node官方 点击下载




其中的 Linux Binaries (x64) 链接就是我们需要的了

如何想要找旧版本,可以点击以前的发行版本


选择你想要的版本,



然后选择 node-xxx-linux-arm64.tar.gz 就可以了



相关推荐
腾讯TNTWeb前端团队5 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰9 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪9 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪9 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy10 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom10 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom10 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom10 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom11 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom11 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试