CUBERWR/BLOG

Picgo+自建telegraph代理图床实现无限图片存储

2023.07.24

已更换新方案 使用go语言实现picgo部分功能代理搭建仍参照本文

使用go语言重写了picgo upload功能,替代很重的node+picgo实现与obsidian插件image auto upload plugin配和自动上传图片到图床

为什么要这么做

telegraph提供匿名的图片存储,单张图片限制5M,基本不存在被和谐的情况,并且不限数量

telegrah在国内无法访问,所以基于telegraph的图床在国内也是无法使用,但是cloudflare的workers在国内是可以使用的,所以打算使用worker代理访问telegraph

过程记录

cloudfalre workers部分:

考虑到以后可能还会扩充功能,这里先把router功能独立出来

入口文件worker.js

import router from './router';
export default {
    async fetch(request, env, ctx) {
        return router.handle(request)
    }
}

路由和请求处理router.js

import { Router } from 'itty-router';
const router = Router();
router.get('/file/:id', handleRequest)
router.post('/upload', handleRequest)
async function handleRequest(request) {
    const url = new URL(request.url);
    const response = fetch('https://telegra.ph/' + url.pathname + url.search, {
        method: request.method,
        headers: request.headers,
        body: request.body,
    });
    return response
}
router.all('*', () => new Response('Not Found.', { status: 404 }));

export default router;

之后就可以用worker的域名加上upload或者file路径来进行上传和访问图片,默认的worker域名容易被墙,换自己域名比较稳定

picgo部分:

这里需要写一个picgo的uploader插件来完成对我们自建图床的上传和取回url,参考官方插件模板在你的picgo配置文件目录初始化一个空插件,初始化完成之后,修改生成的文件的src/index.js,改成如下内容:

const handle = async ctx => {
  let output = ctx.output
  output = await Promise.all(
    output.map(async e => {
      e.imgUrl = await upload(e.buffer, e.filename)
      e.url = e.imgUrl
      return e
    })
  )
  ctx.output = output
  return ctx
}

async function upload(buffer, filename) {
  const { lookup } = require('mime-types')
  let img = new FormData()
  const file = new Blob([buffer], { type: lookup(filename) });
  img.set('file', file, filename)
  let res = await fetch("https://telegra.ph/upload", {
    "body": img,
    "method": "POST"
  })
  res = await res.json()
  return 'https://telegra.ph' + res[0].src
}

module.exports = ctx => {
  const register = () => {
    ctx.helper.uploader.register('telegraph', { handle })
  }
  return {
    register,
    uploader: 'telegraph'  // 请将uploader的id注册在这里
  }
}

需要在插件根的目录执行npm i mime-types来安装mime-types,我写的这个需要mime-types判断类型,之后参照插件测试来安装插件,picgo配置文件中开启并选用刚写的插件:

{
  "picBed": {
    "uploader": "telegraph",
    "current": "telegraph"
  },
  "picgoPlugins": {
    "picgo-plugin-telegraph": true
  }
}

注意这里的插件的名称和id是你创建时候的名称和在上面代码里注册的idtelegraph

配置完成之后正常的使用picgo即可