#教程# 使用Telegraph零成本构建免费的图像托管/无审查/可以上传任何文件,不仅仅是图像文件

前言

今天在 LOC 闲逛,发现了个 Telegraph-Image-Hosting 图床,有用过Telegraph的朋友,应该都知道发布是不需要登录的,匿名发布即可,上传图片仅需点图片按钮。通过抓包分析发现向Telegraph-API发送 POST 请求,即可返回外链。(2023/10/21 更新内容)

图片[1] - #教程# 使用Telegraph零成本构建免费的图像托管/无审查/可以上传任何文件,不仅仅是图像文件 - 云线路

官方 GitHub

安装说明

利用 CF Workers 反代官方 telegra.ph 实现无需 PHP 空间,单个首页文件 index.html 就能完成整个站点。

本站演示

创建 CF Workres

反代官方 /upload 上传地址,注意是在账号下创建,不是在域名下创建;

Workers 和 Pages >> 创建应用程序 >> Workers >> 输入名称 >> 部署 >>

创建服务后点快捷编辑,在代码区编辑代码为:

async function handleRequest(request) {
    const { origin, pathname, searchParams } = new URL(request.url);
    const param = searchParams.toString() ? "?" + searchParams.toString() : "";
    const requestHeaders = request.headers.get("Access-Control-Request-Headers");
    const requestMethod = request.headers.get("Access-Control-Request-Method");
    const requestOrigin = request.headers.get("Origin") ? request.headers.get("Origin") : origin;
    
    // 响应预检请求
    if (request.method == "OPTIONS") {
        return new Response('{"Access": "OPTIONS"}', {
            status: 200,
            headers: {
                "Access-Control-Allow-Origin": requestOrigin ? requestOrigin : "*", //不限制请求来源
                //"Access-Control-Allow-Origin": "https://yunimg.cc",      //限制 CROS 域名,上下两个都要改你自己的
                "Access-Control-Allow-Credentials": "true",
                "Access-Control-Allow-Headers": requestHeaders ? requestHeaders : "*",
                "Access-Control-Allow-Methods": requestMethod ? requestMethod : "*",
                "Content-Type": "application/json",
            }
        });
    }
    
    // 处理正式请求
    const newRequest = new Request("https://telegra.ph/upload" + pathname + param, request);
    // 请求头删除来源
    newRequest.headers.set("referrer-policy", "no-referrer");
    newRequest.headers.delete("Referer");
    newRequest.headers.delete("Origin");
    // 发起请求
    const response = await fetch(newRequest);
    const newResponse = new Response(response.body, response);
    
    // 处理响应
    newResponse.headers.set("Access-Control-Allow-Origin", requestOrigin ? requestOrigin : "*");
    //newResponse.headers.set("Access-Control-Allow-Origin", "https://yunimg.cc");  //限制 CROS 域名,上下两个都要改你自己的
    newResponse.headers.set("Access-Control-Allow-Credentials", "true");
    newResponse.headers.set("Access-Control-Allow-Headers", requestHeaders ? requestHeaders : "*");
    newResponse.headers.set("Access-Control-Allow-Methods", requestMethod ? requestMethod : "*");
    newResponse.headers.set('Access-Control-Expose-Headers', '*');
    newResponse.headers.set("Content-Type", "application/json");
    return newResponse;
}
addEventListener('fetch', event => {
    event.respondWith(handleRequest(event.request));
})

保存后得到一个 api.xxx.workers.dev 的域名,因为 workers.dev 域名国内有些地方是被墙了的,所以要用一个 NS 在 CF 的域名来反代这个 api.xxx.workers.dev

返回首页,进入需要反代的域名 — DNS — 添加一条 A 记录:

图片[2] - #教程# 使用Telegraph零成本构建免费的图像托管/无审查/可以上传任何文件,不仅仅是图像文件 - 云线路

Workres 路由设置

Workers 路由 — HTTP 路由 — 添加路由 — 进入后就 2 个选填,路由和服务,按照提示填写即可。

这样就完成整个反代过程,然后在官方下载代码,这里只需要首页文件 index.html 即可。

下面是本站修改美化后的 index.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>
	<meta name="description" content="基于 Telegraph 免费和无限的图像托管">
	<link rel="shortcut icon" href="//wsrv.nl/?url=telegra.ph/file/50fee15aa10cfacf2fd76.png" type="image/x-icon" />	
    <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <style>
        body {
            font-family: Arial, sans-serif;
            background:#f6f8fa url(//wsrv.nl/?url=telegra.ph/file/b748d085303e38901fbee.png) top;
        }

        .container {
            max-width: 600px;
            margin: 35px auto;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0 0 15px rgba(0,0,0,0.2);
			background-color: rgba(246,248,250,0.5);
        }

        .upload-btn-wrapper {
            position: relative;
            justify-content: center;
            align-items: center;
            overflow: hidden;
            display: flex;
            background-color: #007BFF;
            color: #FFF;
            border-radius: 5px;
            padding: 10px;
            cursor: pointer;
            transition: background-color 0.3s;
        }

        .upload-btn-wrapper:hover {
            background-color: #0056b3;
        }

        .upload-btn-wrapper input[type=file] {
            font-size: 100px;
            position: absolute;
            left: 0;
            top: 0;
            opacity: 0;
        }

        .custom-input-group-append {
            position: relative;
            overflow: hidden;
            display: flex;
        }

        .alert {
            position: fixed;
            z-index: 9999;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            opacity: 0.6;
            padding: 10px;
        }

        .alert.alert-warning {
            color: #fff;
            background-color: #333333;
            border: 1px solid #ddd;
            border-radius: 2px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h2 class="text-center">电报图像托管</h2>
        <p class="text-center text-muted" style="color:red;">免费和无限的图像托管</p>
        <p class="text-center text-muted" style="color:#A569BD;">立即开始上传您的图片,上传图片限制 5M 以内</p>
        <hr>

        <div class="upload-btn-wrapper text-center">
            <span>选择图片</span>
            <input type="file" name="file" id="fileInput" accept="image/png, image/jpeg, image/jpg, image/gif">
        </div>

        <div id="uploadStatus" style="margin-top: 20px;"></div>

        <hr>
        <p align="center">© <script>document.write(new Date().getFullYear())</script> <a href="https://img.yunloc.com" target="_Blank">Yunloc</a> Image. Author <a href="https://t.me/missuo" target="_Blank">Vincent</a>, <a href="https://www.yunloc.com/1738.html" target="_Blank">[ Install Help ]</a></p>
    </div>

    <script>
        const fileInput = document.getElementById('fileInput');
        const uploadStatus = document.getElementById('uploadStatus');

        fileInput.addEventListener('change', function() {
            const file = fileInput.files[0];
            if (file) {
                uploadImage(file);
            }
        });

        function uploadImage(file) {
            const formData = new FormData();
            formData.append('file', file);

            uploadStatus.innerHTML = '<div class="alert alert-info"><i class="glyphicon glyphicon-upload"></i> 上传中,请稍候...</div>';

            fetch('//missuo.ru/upload', {
                method: 'POST',
                body: formData
            })
            .then(response => response.json())
            .then(data => {
                const src = 'https://missuo.ru' + data[0].src;
                const src1 = 'https://images.weserv.nl/?url=telegra.ph' + data[0].src;
                const src2 = 'https://i3.wp.com/telegra.ph' + data[0].src;
                uploadStatus.innerHTML = `
                    <div class="alert alert-success"><i class="glyphicon glyphicon-ok"></i> 上传成功!</div>
                    <div class="text-center">
                        <img src="${src}" class="img-fluid mb-3" alt="Uploaded Image" style="max-width: 100%;">
                    </div>
                    <div class="input-group">
                        <input type="text" class="form-control" style="margin-top: 20px;" id="imageUrl" value="${src}">
                        <div class="custom-input-group-append" style="margin-top: 60px;">
                            <a href="${src}" target="_blank"><button type="button" class="btn btn-primary">在新标签中打开</button></a>
                            <button class="btn btn-primary" type="button" onclick="copyImageUrl('imageUrl')" style="margin-left: 5px;">复制网址</button>
                        </div>
                    </div>					
                    <div class="input-group">
                        <input type="text" class="form-control" style="margin-top: 20px;" id="imageUrl1" value="${src1}">
                        <div class="custom-input-group-append" style="margin-top: 60px;">
                            <a href="${src1}" target="_blank"><button type="button" class="btn btn-primary">在新标签中打开</button></a>
                            <button class="btn btn-primary" type="button" onclick="copyImageUrl('imageUrl1')" style="margin-left: 5px;">复制网址</button>
                        </div>
                    </div>
                    <div class="input-group">
                        <input type="text" class="form-control" style="margin-top: 20px;" id="imageUrl2" value="${src2}">
                        <div class="custom-input-group-append" style="margin-top: 60px;">
                            <a href="${src2}" target="_blank"><button type="button" class="btn btn-primary">在新标签中打开</button></a>
                            <button class="btn btn-primary" type="button" onclick="copyImageUrl('imageUrl2')" style="margin-left: 5px;">复制网址</button>
                        </div>
                    </div>
                `;
                setTimeout(function() {
                    const successAlert = document.querySelector('.alert-success');
                    successAlert.style.display = 'none';
                }, 5000);
            })
            .catch(error => {
                uploadStatus.innerHTML = '<div class="alert alert-danger"><i class="glyphicon glyphicon-remove"></i> 上传失败! 请再试一次...</div>';
            });
        }

        function copyImageUrl(imageUrlId) {
            const imageUrl = document.getElementById(imageUrlId).value;
            navigator.clipboard.writeText(imageUrl)
                .then(function() {
                    const alertBox = document.createElement('div');
                    alertBox.className = 'alert alert-warning';
                    alertBox.innerHTML = '<i class="glyphicon glyphicon-info-sign"></i> 已复制到剪贴板!';
                    document.body.appendChild(alertBox);

                    setTimeout(function() {
                        alertBox.remove();
                    }, 2000);
                })
                .catch(function(error) {
                    console.error('复制失败:', error);
                });
        }
    </script>
</body>
</html>

把 110 行官方反代 missuo.ru/upload 地址改为你的反代域名下就可以用了,(或者直接用也可以,COPY 整个文件上传到自己的 HTML 空间就 OK 了)只需要一个html文件就 OK,博主把它放在阿里云 OSS 上,套上 CF,基本没有费用!

然后按上面的步骤添加 A 记录到 8.8.8.8,打开云朵;

然后添加域名的 Workers 路由为 Workres 创建的那个服务就 OK 了!

演示站点:

总结

Telegraph-Image-Hosting是免费的无限带宽(但会消耗你 VPS 的流量),无审查(可以上传 NSFW 图像),可以上传任何文件,而不仅仅是图像文件。

但是Telegraph-Image-Hosting 单个文件不能超过 5MB,套 CF 后国内的访问速度可能并不理想。

© 本站文章随意转载,但请注明出处!
THE END
点赞6 分享
评论 共13条
头像
务必使用真实的邮箱地址评论,虚假邮箱的评论将不通过审核及无回复。
提交
头像

昵称

取消
昵称表情代码图片
    • 头像游客0
    • 头像游客0
    • 头像游客0
    • 头像游客0
    • 头像游客0
    • 头像QX0
    • 头像QX0
    • 头像11110