前言
最近搭建了一个兰空图床,我想挂载一个储存做为我的长期存储图片的图床,想起了之前白嫖的InfiniCLOUD,我的免费额度已经到四十多G了。所以顺便写了一个反代webdav的代码,在1panel一键部署。
环境准备
所需工具和环境:
开发环境:
- 操作系统:Debian
- WebDAV 服务:InfiniCLOUD 免费账户
功能实现
我希望实现以下目标:
- 移除直接访问 WebDAV 时的密码验证步骤。
- 根据用户访问路径动态代理文件或目录。
- 通过服务器自动完成 Basic Auth 验证。
核心代码解析
以下是代码的主要逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| const express = require('express'); const axios = require('axios'); const path = require('path'); const mime = require('mime-types'); const app = express();
const WEBDAV_URL = 'webdav地址'; const WEBDAV_USERNAME = '账号'; const WEBDAV_PASSWORD = '密码';
const basicAuth = Buffer.from(`${WEBDAV_USERNAME}:${WEBDAV_PASSWORD}`).toString('base64');
app.get('*', async (req, res) => { try { let requestPath = req.path;
const fullUrl = WEBDAV_URL + (requestPath.startsWith('/') ? requestPath.substring(1) : requestPath);
const response = await axios({ method: 'GET', url: fullUrl, headers: { 'Authorization': `Basic ${basicAuth}` }, responseType: 'stream' });
const contentType = mime.lookup(path.extname(requestPath)) || 'application/octet-stream'; res.setHeader('Content-Type', contentType); if (response.headers['content-length']) res.setHeader('Content-Length', response.headers['content-length']); if (response.headers['last-modified']) res.setHeader('Last-Modified', response.headers['last-modified']);
response.data.pipe(res);
} catch (error) { console.error('Error:', error.message); res.status(error.response?.status || 500).send({ error: '访问 WebDAV 资源失败' }); } });
const PORT = process.env.PORT || 3090; app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); });
|
package.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| { "name": "webdav-proxy", "version": "1.0.0", "description": "A proxy server for WebDAV file access", "main": "server.js", "scripts": { "start": "node server.js", "dev": "nodemon server.js" }, "keywords": [ "webdav", "proxy", "file-server" ], "author": "", "license": "ISC", "dependencies": { "axios": "^1.6.2", "express": "^4.18.2", "mime-types": "^2.1.35" }, "devDependencies": { "nodemon": "^3.0.2" }, "engines": { "node": ">=14.0.0" } }
|
核心逻辑
WebDAV 配置
定义 WebDAV 服务的 URL 和账户认证信息,并利用 Base64 编码创建 Basic Auth 头。
动态路径映射
根据用户访问的路径,动态构造完整的 WebDAV 请求 URL。
流式传输文件
使用 axios
的 responseType: 'stream'
参数将 WebDAV 响应直接传递给客户端,减少内存占用。
设置 MIME 类型
通过 mime-types
库,根据文件后缀设置正确的 Content-Type
,保证浏览器的文件渲染效果。
部署与运行
- 将两个文件导入服务器的一个文件夹:

随后在 网站-运行环境,选择创建运行环境,选择你存放的文件夹

最后部署即可。