基于cf_workers部署IPFS图床(即开即用,秒部署)

准备工作:
cloudflare账号1
pinata_api
1(申请即可)

操作流程:
1、打开CF创建workers
2、点击右上角编辑代码
3、复制以下代码块粘贴至workers项目内(修改line202-203中的pinata_api)

修改项:
1、新增上传图片网关失效自动切换
2、访问网关源修改为支持大陆地区(谢谢站内其他小伙伴提供的公开网关)

成品站点参考

ps:由于是心血来潮,基于chatgpt码出来的;整体美观度不够 还请勿喷 xhj022

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const url = new URL(request.url)

  // 判断是否是上传请求
  if (url.pathname === '/upload' && request.method === 'POST') {
    const formData = await request.formData()
    const imageFile = formData.get('image')

    if (imageFile) {
      const cid = await uploadToIPFSWithFallback(imageFile)
      if (cid) {
        return new Response(`<!DOCTYPE html>
          <html>
            <head>
              <meta charset="UTF-8">
              <title>图片上传成功</title>
              <style>
                body {
                  font-family: 'Arial', sans-serif;
                  background-color: #ffffff;
                  margin: 0;
                  padding: 0;
                  text-align: center;
                  display: flex;
                  flex-direction: column;
                  justify-content: center;
                  align-items: center;
                  height: 100vh;
                }
                .container {
                  background-color: #ffffff;
                  border-radius: 15px;
                  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
                  padding: 30px;
                  max-width: 600px;
                  width: 100%;
                  margin: 20px;
                }
                h1 {
                  color: #2c3e50;
                  margin-bottom: 20px;
                  font-size: 2.5em;
                }
                p {
                  font-size: 1.2em;
                  color: #34495e;
                }
                a {
                  color: #3498db;
                  text-decoration: none;
                  font-weight: bold;
                }
                a:hover {
                  text-decoration: underline;
                }
                button {
                  background-color: #3498db;
                  color: white;
                  border: none;
                  padding: 15px 30px;
                  border-radius: 8px;
                  cursor: pointer;
                  font-size: 1em;
                  transition: background-color 0.3s ease;
                }
                button:hover {
                  background-color: #2980b9;
                }
                input[type="file"] {
                  margin: 20px 0;
                  border: 1px solid #ddd;
                  border-radius: 5px;
                  padding: 10px;
                  background-color: #f9f9f9;
                }
              </style>
            </head>
            <body>
              <div class="container">
                <h1>上传成功!</h1>
                <p>CID: ${cid}</p>
                <p>访问图片/视频:<a href="https://i0.img2ipfs.com/ipfs/${cid}" target="_blank">点击查看图片/视频</a></p>
              </div>
            </body>
          </html>`, {
          headers: { 'content-type': 'text/html; charset=utf-8' },
        })
      } else {
        return new Response('图片/视频上传失败', { status: 500 })
      }
    }

    return new Response('未找到图片/视频', { status: 400 })
  }

  // 返回美化后的 HTML 上传表单
  return new Response(`<!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>爱跑路的图床</title>
        <style>
          body {
            font-family: 'Arial', sans-serif;
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-size: cover;
            background-position: center;
            background-repeat: no-repeat;
            transition: background-image 1s ease-in-out;
          }
          .container {
            background-color: rgba(255, 255, 255, 0.9);
            border-radius: 15px;
            box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
            padding: 30px;
            max-width: 600px;
            width: 100%;
            text-align: center;
          }
          h1 {
            color: #2c3e50;
            margin-bottom: 20px;
            font-size: 2.5em;
          }
          input[type="file"] {
            margin: 20px 0;
            border: 1px solid #ddd;
            border-radius: 5px;
            padding: 10px;
            background-color: #f9f9f9;
          }
          button {
            background-color: #3498db;
            color: white;
            border: none;
            padding: 15px 30px;
            border-radius: 8px;
            cursor: pointer;
            font-size: 1em;
            transition: background-color 0.3s ease;
          }
          button:hover {
            background-color: #2980b9;
          }
        </style>
        <script>
          function changeBackground() {
            const images = [
              'https://source.unsplash.com/random?landscape',
              'https://source.unsplash.com/random?nature',
              'https://source.unsplash.com/random?mountain',
              'https://source.unsplash.com/random?sea'
            ];
            const randomImage = images[Math.floor(Math.random() * images.length)];
            document.body.style.backgroundImage = \`url('\${randomImage}')\`;
          }

          setInterval(changeBackground, 10000);  // 每 10 秒更换一次背景图
          document.addEventListener('DOMContentLoaded', changeBackground);
        </script>
      </head>
      <body>
        <div class="container">
          <h1>爱跑路的图床</h1>
          <form action="/upload" method="POST" enctype="multipart/form-data">
            <input type="file" name="image" accept="image/*" required>
            <button type="submit">上传图片/视频</button>
          </form>
        </div>
      </body>
    </html>`, {
    headers: { 'content-type': 'text/html; charset=utf-8' },
  })
}

// 使用多个 IPFS 网关上传图片,并在失败时自动切换
async function uploadToIPFSWithFallback(file) {
  const gateways = [
    { url: 'https://api.pinata.cloud/pinning/pinFileToIPFS', headers: {
        'pinata_api_key': 'XXXXX',
        'pinata_secret_api_key': 'XXXXX'
      }},
    { url: 'https://gateway.ipfs.io/api/v0/add' },
    { url: 'https://api.infura.io:5001/api/v0/add' },
    { url: 'https://ipfs.siliconvalley.social/api/v0/add' },
    { url: 'https://cloudflare-ipfs.com/api/v0/add' },
    { url: 'https://dweb.link/api/v0/add' },
    { url: 'https://ipfs.eth.aragon.network/api/v0/add' },
    { url: 'https://nftstorage.link/api/v0/add' },
    { url: 'https://4everland.io/api/v0/add' },
    { url: 'https://ipfs.cyou/api/v0/add' },
    { url: 'https://storry.tv/api/v0/add' },
    { url: 'https://hardbin.com/api/v0/add' },
    { url: 'https://ipfs.runfission.com/api/v0/add' },
    { url: 'https://w3s.link/api/v0/add' },
    { url: 'https://trustless-gateway.link/api/v0/add' },
    { url: 'https://ipfs.ipfs.tech/api/v0/add' },
    { url: 'https://gateway.ipfs.btcscan.org/api/v0/add' },
    { url: 'https://i0.img2ipfs.com/api/v0/add' },
    { url: 'https://ipfs.crossbell.io/api/v0/add' },
    { url: 'https://gateway.ipfsscan.io/api/v0/add' }
  ]

  for (const gateway of gateways) {
    try {
      const cid = await uploadToIPFS(file, gateway.url, gateway.headers || {})
      if (cid) {
        return cid
      }
    } catch (error) {
      console.error(`上传到 ${gateway.url} 失败:`, error)
    }
  }

  return null  // 如果所有网关都失败,返回 null
}

async function uploadToIPFS(file, url, headers) {
  const formData = new FormData()
  formData.append('file', file, 'image.png')  // 确保文件名存在

  const response = await fetch(url, {
    method: 'POST',
    headers: headers,
    body: formData
  })

  if (response.ok) {
    const data = await response.json()
    return data.IpfsHash || data.Hash  // 返回上传文件的 CID
  } else {
    console.error('上传失败', await response.text())  // 输出错误日志
    throw new Error('上传失败')
  }
}
© 版权声明
THE END
喜欢就支持一下吧
点赞11赞赏 分享
评论 抢沙发

    暂无评论内容