├── google_translate_api.js ├── README.md └── google.js /google_translate_api.js: -------------------------------------------------------------------------------- 1 | const TRANSLATE_API = 'https://translate.googleapis.com'; 2 | 3 | addEventListener('fetch', event => { 4 | event.respondWith(handleRequest(event.request)) 5 | }) 6 | 7 | async function handleRequest(request) { 8 | const url = new URL(request.url); 9 | url.host = TRANSLATE_API.replace(/^https?:\/\//, ''); 10 | 11 | const modifiedRequest = new Request(url.toString(), { 12 | headers: request.headers, 13 | method: request.method, 14 | body: request.body, 15 | redirect: 'follow' 16 | }); 17 | 18 | const response = await fetch(modifiedRequest); 19 | const modifiedResponse = new Response(response.body, response); 20 | 21 | // 添加允许跨域访问的响应头 22 | modifiedResponse.headers.set('Access-Control-Allow-Origin', '*'); 23 | 24 | return modifiedResponse; 25 | } 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 据观察,谷歌已经加大了对cloudflare回源ip的封锁力度,直接反代api和ipv6.google.com的时代基本结束了,仅保留此项目作为参考。 2 | 3 | 4 | # workers_proxy_for_Google 5 | - Due to Google had ban the ipv4 address of cloudflare, so i use ipv6.google.com as back-to-source hostname for google search, but ipv6.google.com doesn't support image search, so when using image search, it will jump back to www.google.com automatically. 6 | - 由于谷歌搜索屏蔽了 cloudflare 回源的ipv4地址,因此在这里我使用ipv6.google.com作为回源主机名,但是ipv6.google.com不支持图片搜索,又做了一些额外的修改以在使用图片搜索的时候跳转回www.google.com。 7 | 8 | #### Additional for mainland chinese users/适用于中国大陆用户: 9 | - 由于中国大陆屏蔽了workers.dev域名,如需使用,请参考这篇文章绑定自己的域名: 10 | - https://cloud.tencent.com/developer/article/1948298 11 | 12 | #### How to use/使用方法: 13 | - Read this article/可以参考这篇文章: https://xuwuyibing.github.io/googlemirror/ 14 | 15 | #### 2023更新:cloudflare现在已被国内运营商严重限速,有可能导致在谷歌镜像的搜索首页无法搜索,可以将其设置为默认搜索引擎,在地址栏搜索,方法以edge为例: 16 | 1. 打开浏览器设置 17 | 2. 搜索“搜索引擎” 18 | 3. 点击 地址栏与搜索-管理搜索引擎-添加 19 | 4. 搜索引擎名字和快捷方式随便填,最后一栏填入 20 | https://[你绑定的域名]/search?q=%s 21 | 5. 将其改为默认设置,即可在浏览器地址栏搜索 22 | 23 | #### 2024 Update: 部署谷歌翻译API镜像 24 | 时过境迁,谷歌翻译也终于没了中国版。本来想着谷歌翻译api的镜像非常好做,没想到github似乎没有相关的代码库,就顺便新增了google_translate_api.js,和部署谷歌镜像类似,复制粘贴,并绑定二级域名即可。 25 | 翻译API镜像,个人推荐结合翻译插件食用: 26 | - 划词翻译:https://hcfy.app/blog/2022/09/28/ggg#%E6%96%B9%E6%A1%88-c%E4%BD%BF%E7%94%A8%E9%95%9C%E5%83%8F%E5%9C%B0%E5%9D%80%E6%9C%80%E7%AE%80%E5%8D%95 27 | - 沉浸式翻译:https://github.com/immersive-translate/immersive-translate/issues/307 28 | - CopyTranslate: https://copytranslator.github.io/guide/questions.html 29 | 30 | 参考: 31 | 1. https://github.com/klightso/Workers-Proxy-1 32 | 2. https://github.com/xiaoyang-sde/reflare 33 | -------------------------------------------------------------------------------- /google.js: -------------------------------------------------------------------------------- 1 | // 反代目标网站 2 | const upstream = 'ipv6.google.com.hk' 3 | const upstream_v4 = 'www.google.com.hk' 4 | 5 | // 访问区域黑名单(按需设置). 6 | const blocked_region = ['TK'] 7 | 8 | //资源重定向 9 | const replace_dict = { 10 | '$upstream': '$custom_domain', 11 | 12 | 'www.google.com/': 'YOUR SUB DOMAIN/', //填入你的子域名 13 | 14 | 'gstatic.com': 'gstatic.cn', 15 | 16 | 'ajax.googleapis.com': 'ajax.lug.ustc.edu.cn', 17 | 'fonts.googleapis.com': 'fonts.googleapis.cn', 18 | 'themes.googleusercontent.com': 'google-themes.lug.ustc.edu.cn', 19 | 'www.gravatar.com/avatar':'dn-qiniu-avatar.qbox.me/avatar', 20 | 21 | 'www.google.co.jp': '$custom_domain', 22 | 'www.google.com.sg': '$custom_domain', 23 | 'books.google.com.hk': '$custom_domain', 24 | 'books.google.co.jp': '$custom_domain', 25 | 'books.google.com.sg': '$custom_domain', 26 | 'maps.google.com.hk': '$custom_domain', 27 | 'maps.google.co.jp': '$custom_domain', 28 | 'maps.google.com.sg': '$custom_domain', 29 | 'maps.google.com': '$custom_domain', 30 | 'books.google.com': '$custom_domain' 31 | 32 | } 33 | 34 | addEventListener('fetch', event => { 35 | event.respondWith(fetchAndApply(event.request)); 36 | }) 37 | 38 | async function fetchAndApply(request) { 39 | 40 | const region = request.headers.get('cf-ipcountry').toUpperCase(); 41 | //const ip_address = request.headers.get('cf-connecting-ip'); 42 | const user_agent = request.headers.get('user-agent'); 43 | 44 | let response = null; 45 | let url = new URL(request.url); 46 | let url_host = url.host; 47 | 48 | if (url.protocol == 'http:') { 49 | url.protocol = 'https:' 50 | response = Response.redirect(url.href); 51 | return response; 52 | } 53 | 54 | //检查是否为图片搜索 55 | var key=url.href; 56 | var ikey1='tbm=isch'; 57 | var ikey2='/img'; 58 | if ((key.search(ikey1)==-1)&(key.search(ikey2)==-1)){ 59 | var upstream_domain = upstream; 60 | }else{ 61 | var upstream_domain = upstream_v4; 62 | } 63 | 64 | url.host = upstream_domain; 65 | 66 | if (blocked_region.includes(region)) { 67 | response = new Response('Access denied: WorkersProxy is not available in your region yet.', { 68 | status: 403 69 | }); 70 | } else{ 71 | let method = request.method; 72 | let request_headers = request.headers; 73 | let new_request_headers = new Headers(request_headers); 74 | 75 | new_request_headers.set('Host', upstream_domain); 76 | new_request_headers.set('Referer', url.href); 77 | 78 | let original_response = await fetch(url.href, { 79 | method: method, 80 | headers: new_request_headers 81 | }) 82 | 83 | let original_response_clone = original_response.clone(); 84 | let original_text = null; 85 | let response_headers = original_response.headers; 86 | let new_response_headers = new Headers(response_headers); 87 | let status = original_response.status; 88 | 89 | new_response_headers.set('cache-control' ,'public, max-age=14400') 90 | new_response_headers.set('access-control-allow-origin', '*'); 91 | new_response_headers.set('access-control-allow-credentials', true); 92 | new_response_headers.delete('content-security-policy'); 93 | new_response_headers.delete('content-security-policy-report-only'); 94 | new_response_headers.delete('clear-site-data'); 95 | 96 | const content_type = new_response_headers.get('content-type'); 97 | if (content_type.includes('text/html')&& content_type.includes('UTF-8')) {// && content_type.includes('UTF-8') 98 | original_text = await replace_response_text(original_response_clone, upstream_domain, url_host); 99 | } else { 100 | original_text = original_response_clone.body 101 | } 102 | 103 | response = new Response(original_text, { 104 | status, 105 | headers: new_response_headers 106 | }) 107 | } 108 | return response; 109 | } 110 | 111 | 112 | async function replace_response_text(response, upstream_domain, host_name) { 113 | let text = await response.text() 114 | 115 | var i, j; 116 | for (i in replace_dict) { 117 | j = replace_dict[i] 118 | if (i == '$upstream') { 119 | i = upstream_domain 120 | } else if (i == '$custom_domain') { 121 | i = host_name 122 | } 123 | 124 | if (j == '$upstream') { 125 | j = upstream_domain 126 | } else if (j == '$custom_domain') { 127 | j = host_name 128 | } 129 | 130 | let re = new RegExp(i, 'g') 131 | text = text.replace(re, j); 132 | } 133 | 134 | return text; 135 | } 136 | --------------------------------------------------------------------------------