You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Node API将图片存储到共享主机服务商

实现方案

Heroku免费Dyno采用临时文件系统,每次部署、休眠重启后本地存储的文件都会被清空,因此无法直接使用multer存储文件到Dyno本地,使用你手头的共享主机作为独立存储节点是完全可行的,具体实现流程如下:

1. 配置共享主机端上传服务

你需要在共享主机上部署一个极简的上传接收服务,仅负责文件接收、存储、返回公网访问地址,支持Node.js或PHP两种实现方式:

  • 核心逻辑:接收上传请求→鉴权→将文件存入共享主机的公开可访问目录→返回文件的公网访问URL
  • 必须配置:确保存储的图片可以通过固定公网路径直接访问,格式示例为https://<你的共享主机域名>/uploads/<文件名>
  • 鉴权配置:在请求头中增加自定义密钥校验,避免恶意上传

Node.js实现示例

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

// 配置存储路径为共享主机的公开可访问目录
const storage = multer.diskStorage({
  destination: (req, file, cb) => cb(null, '/path/to/your/shared/host/public/uploads'),
  filename: (req, file, cb) => {
    // 生成唯一文件名避免覆盖
    const uniqueName = `${Date.now()}-${Math.round(Math.random() * 1e9)}-${file.originalname}`;
    cb(null, uniqueName);
  }
});
const upload = multer({ storage });

// 自定义鉴权中间件
const uploadAuth = (req, res, next) => {
  if (req.headers['x-upload-key'] !== 'YOUR_CUSTOM_SECRET_KEY') {
    return res.status(403).send('Unauthorized');
  }
  next();
};

// 上传接口
app.post('/upload', uploadAuth, upload.single('image'), (req, res) => {
  const publicUrl = `https://<你的共享主机域名>/uploads/${req.file.filename}`;
  res.json({ url: publicUrl });
});

app.listen(3000, () => console.log('Upload service running'));

PHP实现示例(适用于仅支持PHP的共享主机)

// upload.php
<?php
header('Content-Type: application/json');
// 鉴权
if ($_SERVER['HTTP_X_UPLOAD_KEY'] !== 'YOUR_CUSTOM_SECRET_KEY') {
  http_response_code(403);
  echo json_encode(['error' => 'Unauthorized']);
  exit;
}
// 生成唯一文件名
$fileName = time() . '-' . rand(100000, 999999) . '-' . $_FILES['image']['name'];
$savePath = '/path/to/your/shared/host/public/uploads/' . $fileName;
// 存储文件
if (move_uploaded_file($_FILES['image']['tmp_name'], $savePath)) {
  $publicUrl = 'https://<你的共享主机域名>/uploads/' . $fileName;
  echo json_encode(['url' => $publicUrl]);
} else {
  http_response_code(500);
  echo json_encode(['error' => 'Upload failed']);
}
?>

2. 修改Heroku端Node.js API逻辑

将原multer本地存储改为内存存储,收到前端上传请求后直接转发到共享主机的上传接口,拿到返回的URL后写入Postgres数据库即可:

const express = require('express');
const multer = require('multer');
const axios = require('axios');
const FormData = require('form-data');
const { Pool } = require('pg');
const app = express();
const db = new Pool({ /* 你的Postgres连接配置 */ });

// 配置multer使用内存存储,不写入本地磁盘
const storage = multer.memoryStorage();
const upload = multer({ storage });

// 前端调用的上传接口
app.post('/api/upload', upload.single('image'), async (req, res) => {
  try {
    // 构造表单数据转发到共享主机
    const form = new FormData();
    form.append('image', req.file.buffer, req.file.originalname);
    
    // 请求共享主机上传接口
    const uploadRes = await axios.post('https://<你的共享主机域名>/upload', form, {
      headers: {
        ...form.getHeaders(),
        'x-upload-key': 'YOUR_CUSTOM_SECRET_KEY'
      }
    });

    const imageUrl = uploadRes.data.url;
    // 将图片URL写入Postgres数据库,可根据业务逻辑关联对应记录
    await db.query(
      'INSERT INTO images (url, relate_id, created_at) VALUES ($1, $2, NOW())',
      [imageUrl, req.body.relate_id]
    );

    res.json({ success: true, url: imageUrl });
  } catch (err) {
    res.status(500).json({ success: false, error: 'Upload failed' });
  }
});

app.listen(process.env.PORT || 3000);

3. 额外优化建议

  • 给共享主机的uploads目录配置防盗链规则,仅允许你的前端域名和Heroku域名访问,避免带宽被恶意消耗
  • 配置图片缓存规则,设置较长的Cache-Control有效期,减少重复请求的带宽占用
  • 可增加文件格式、大小校验,避免非法文件上传
  • 定期备份共享主机上的图片文件,避免数据丢失

内容的提问来源于stack exchange,提问作者Sarthak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 11:36:04