前言
当处于小图床容易跑路,云服务商oss储存又不想花钱的尴尬处境上,故想用GitHub作为免费图床托管,cloudflare进行代理加速实现图床搭建。
方案的主要思路是使用 Cloudflare 的 Workers 来代理 github 私有仓库中文件的地址,并绑定自己的域名进行使用。该方案主要优势是:
Github 服务稳定,不会跑路。
使用的是 Github 的私有仓库,存储里的文件列表并不会像公开仓库一样全部对外暴露,有一定的安全性。
使用自己的域名,方便以后可能的服务迁移。
免费 :GitHub和Cloudflare都提供免费的基本服务,这意味着你可以使用它们搭建图床而不需要额外的费用。
稳定性和可靠性 :GitHub和Cloudflare都是知名的服务提供商,拥有稳定的基础架构和高可用性。GitHub 文件托管服务,在稳定性和可靠性方面表现良好。Cloudflare的CDN服务可以加速图像加载,提高用户体验。
全球分发 :通过使用Cloudflare的CDN,你的图片可以在全球范围内快速分发,减少加载时间并提升访问速度。
自定义域名 :你可以使用自己的域名来访问图床,这为你的图床增加了专业性和个性化。
版本控制 :GitHub提供版本控制功能,你可以管理和跟踪你上传的图片文件的变化。这对于团队协作或者回溯图片历史非常有用。
安全性 :GitHub和Cloudflare都有安全性功能,包括SSL/TLS加密和防御DDoS攻击等。这些功能可以保护你的图片和用户数据。
你需要准备的东西有:
一个域名。
Cloudflare 账号。
github 账号。
本篇文章参考知乎用户 的文章 ,并修改了代码的两处警告完成。感谢大佬!!!
教程
创建一个GitHub私有仓库
这个部分省略,我相信没有人不会操作。
创建GitHub令牌直达连接
点击右上角用户头像,进入 Settings(设置)页面。
在这个页面中左侧侧边栏选择 Developer settings(开发人员设置)
然后点击 Personal access tokens(个人访问令牌)菜单里的 Token classic,点击 Generate new token 开始创建一个新的令牌,注意一定要选择 classic 方式。
在创建页面中,填写 Note 为“图床”,Expiration(过期时间)为 No expiration(永久),在下面的Select scopes(选择权限范围)如下图勾选 repo。最后点击 generate token 生成令牌即可。
在生成后的页面中会看到新生成的github令牌,该令牌后面会使用到。
务必将令牌保存起来 ,放在一个安全的地方,页面关掉后就看不到了。
在cloudflare创建用于代理的 Worker
打开cloudflare Workers
创建worker
修改名称并部署
编辑
贴入代码
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 const upstream = "raw.githubusercontent.com" ;const upstream_path = "****" ;const github_token = "****" ;const upstream_mobile = upstream;const blocked_region = [];const blocked_ip_address = ["0.0.0.0" , "127.0.0.1" ];const https = true ;const disable_cache = false ;const replace_dict = { $upstream : "$custom_domain" , }; addEventListener ("fetch" , (event ) => { event.respondWith (fetchAndApply (event.request )); }); async function fetchAndApply (request ) { const region = request.headers .get ("cf-ipcountry" )?.toUpperCase (); const ip_address = request.headers .get ("cf-connecting-ip" ); const user_agent = request.headers .get ("user-agent" ); let response = null ; let url = new URL (request.url ); let url_hostname = url.hostname ; if (https == true ) { url.protocol = "https:" ; } else { url.protocol = "http:" ; } if (await device_status (user_agent)) { var upstream_domain = upstream; } else { var upstream_domain = upstream_mobile; } url.host = upstream_domain; if (url.pathname == "/" ) { url.pathname = upstream_path; } else { url.pathname = upstream_path + url.pathname ; } if (blocked_region.includes (region)) { response = new Response ( "Access denied: WorkersProxy is not available in your region yet." , { status : 403 , } ); } else if (blocked_ip_address.includes (ip_address)) { response = new Response ( "Access denied: Your IP address is blocked by WorkersProxy." , { status : 403 , } ); } else { let method = request.method ; let request_headers = request.headers ; let new_request_headers = new Headers (request_headers); new_request_headers.set ("Host" , upstream_domain); new_request_headers.set ("Referer" , url.protocol + "//" + url_hostname); new_request_headers.set ("Authorization" , "token " + github_token); let original_response = await fetch (url.href , { method : method, headers : new_request_headers, body : request.body , }); let connection_upgrade = new_request_headers.get ("Upgrade" ); if (connection_upgrade && connection_upgrade.toLowerCase () == "websocket" ) { return original_response; } let original_response_clone = original_response.clone (); let original_text = null ; let response_headers = original_response.headers ; let new_response_headers = new Headers (response_headers); let status = original_response.status ; if (disable_cache) { new_response_headers.set ("Cache-Control" , "no-store" ); } else { new_response_headers.set ("Cache-Control" , "max-age=43200000" ); } new_response_headers.set ("access-control-allow-origin" , "*" ); new_response_headers.set ("access-control-allow-credentials" , "true" ); new_response_headers.delete ("content-security-policy" ); new_response_headers.delete ("content-security-policy-report-only" ); new_response_headers.delete ("clear-site-data" ); if (new_response_headers.get ("x-pjax-url" )) { new_response_headers.set ( "x-pjax-url" , response_headers .get ("x-pjax-url" ) .replace ("//" + upstream_domain, "//" + url_hostname) ); } const content_type = new_response_headers.get ("content-type" ); if ( content_type != null && content_type.includes ("text/html" ) && content_type.includes ("UTF-8" ) ) { original_text = await replace_response_text ( original_response_clone, upstream_domain, url_hostname ); } else { original_text = original_response_clone.body ; } response = new Response (original_text, { status, headers : new_response_headers, }); } return response; } async function replace_response_text (response, upstream_domain, host_name ) { let text = await response.text (); var i, j; for (i in replace_dict) { j = replace_dict[i]; if (i == "$upstream" ) { i = upstream_domain; } else if (i == "$custom_domain" ) { i = host_name; } if (j == "$upstream" ) { j = upstream_domain; } else if (j == "$custom_domain" ) { j = host_name; } let re = new RegExp (i, "g" ); text = text.replace (re, j); } return text; } async function device_status (user_agent_info ) { var agents = [ "Android" , "iPhone" , "SymbianOS" , "Windows Phone" , "iPad" , "iPod" , ]; var flag = true ; for (var v = 0 ; v < agents.length ; v++) { if (user_agent_info.indexOf (agents[v]) > 0 ) { flag = false ; break ; } } return flag; }
需要修改的地方有
1 2 3 4 5 6 7 const upstream_path = "****" ;const github_token = "****" ;
保存并部署
绑定域名
由于cloud flare只支持托管在cloudflare的域名,所以你需要把域名的DNS指向它提供的。在cloudflare左边的网站进去之后就可以看到应该把dns服务器指向的服务器。由于我一直都用cloudflare这里就不方便做展示。
点击触发器绑定自己的域名
之后回到picgo就可配置相关的上传服务。
该封面图片由sfkjrgk 在Pixabay 上发布