首页
文章导航
导航
壁纸
留言板
更多
直播
友链
统计
关于
Search
1
部署在CF的轻量化导航页面,可移动卡片式书签,方便管理
15 阅读
2
bpb面板搭建【有时效性,可能1001用不了】
15 阅读
3
一段代码简单在谷歌colab内搭建vpn,完全免费科学上网工具,全网高速免费机场节点抓取
14 阅读
4
使用 grok 智能每天发送最新订阅链接
14 阅读
5
轻松部署无限节点代理池!
12 阅读
默认
日常
学习
技术
登录
Search
标签搜索
cloudflare
白嫖
CF
docker
安装
脚本
壁纸
图片
Linux
Caddy
代码
哪吒
节点
域名
github
搭建
桌面壁纸
手机壁纸
NAT
LXC
ws01
累计撰写
126
篇文章
累计收到
130
条评论
首页
栏目
默认
日常
学习
技术
页面
文章导航
导航
壁纸
留言板
直播
友链
统计
关于
搜索到
94
篇与
的结果
2025-07-16
cloudflare上免费部署随机地址生成器
cloudflare免费部署随机地址生成器github项目 这是一个基于 Cloudflare Workers 的随机地址生成器,可以生成全球多个国家的真实地址、姓名和电话号码。 本项目基于 Real-Address-Generator 做了一些样式和逻辑上的调整和优化。一、 主要功能 ,爱好者可以自己修改部署支持多个国家/地区的地址生成根据不同国家生成符合当地特色的姓名生成符合各国格式的电话号码实时地图预览地址保存和管理一键复制信息二、部署到 Cloudflare Workers1、原项目代码// 国家坐标数据 const countryCoordinates = { "US": [{ lat: 37.7749, lng: -122.4194 }, { lat: 34.0522, lng: -118.2437 }], "UK": [{ lat: 51.5074, lng: -0.1278 }, { lat: 53.4808, lng: -2.2426 }], "FR": [{ lat: 48.8566, lng: 2.3522 }, { lat: 45.7640, lng: 4.8357 }], "DE": [{ lat: 52.5200, lng: 13.4050 }, { lat: 48.1351, lng: 11.5820 }], "CN": [{ lat: 39.9042, lng: 116.4074 }, { lat: 31.2304, lng: 121.4737 }], "TW": [{ lat: 25.0330, lng: 121.5654 }, { lat: 22.6273, lng: 120.3014 }], "HK": [{ lat: 22.3193, lng: 114.1694 },{ lat: 22.3964, lng: 114.1095 }], "JP": [{ lat: 35.6895, lng: 139.6917 }, { lat: 34.6937, lng: 135.5023 }], "IN": [{ lat: 28.6139, lng: 77.2090 }, { lat: 19.0760, lng: 72.8777 }], "AU": [{ lat: -33.8688, lng: 151.2093 }, { lat: -37.8136, lng: 144.9631 }], "BR": [{ lat: -23.5505, lng: -46.6333 }, { lat: -22.9068, lng: -43.1729 }], "CA": [{ lat: 43.651070, lng: -79.347015 }, { lat: 45.501690, lng: -73.567253 }], "RU": [{ lat: 55.7558, lng: 37.6173 }, { lat: 59.9343, lng: 30.3351 }], "ZA": [{ lat: -33.9249, lng: 18.4241 }, { lat: -26.2041, lng: 28.0473 }], "MX": [{ lat: 19.4326, lng: -99.1332 }, { lat: 20.6597, lng: -103.3496 }], "KR": [{ lat: 37.5665, lng: 126.9780 }, { lat: 35.1796, lng: 129.0756 }], "IT": [{ lat: 41.9028, lng: 12.4964 }, { lat: 45.4642, lng: 9.1900 }], "ES": [{ lat: 40.4168, lng: -3.7038 }, { lat: 41.3851, lng: 2.1734 }], "TR": [{ lat: 41.0082, lng: 28.9784 }, { lat: 39.9334, lng: 32.8597 }], "SA": [{ lat: 24.7136, lng: 46.6753 }, { lat: 21.3891, lng: 39.8579 }], "AR": [{ lat: -34.6037, lng: -58.3816 }, { lat: -31.4201, lng: -64.1888 }], "EG": [{ lat: 30.0444, lng: 31.2357 }, { lat: 31.2156, lng: 29.9553 }], "NG": [{ lat: 6.5244, lng: 3.3792 }, { lat: 9.0579, lng: 7.4951 }], "ID": [{ lat: -6.2088, lng: 106.8456 }, { lat: -7.7956, lng: 110.3695 }] }; // 姓名数据 const namesByCountry = { "CN": { first: ["Li", "Wang", "Zhang", "Liu", "Chen", "Yang", "Huang", "Zhao", "Wu", "Zhou", "Xu", "Sun", "Ma", "Zhu", "Hu", "Guo", "He", "Gao", "Lin", "Zheng"], last: ["Wei", "Fang", "Na", "Xiuying", "Min", "Jing", "Li", "Qiang", "Lei", "Jun", "Yang", "Yong", "Yan", "Jie", "Tao", "Ming", "Chao", "Xiulan", "Xia", "Ping"] }, "JP": { first: ["Sato", "Suzuki", "Takahashi", "Tanaka", "Watanabe", "Ito", "Yamamoto", "Nakamura", "Kobayashi", "Kato"], last: ["Shota", "Ren", "Hina", "Yui", "Hiroto", "Sota", "Yota", "Misaki", "Nanami", "Yuto"] }, "KR": { first: ["Kim", "Lee", "Park", "Choi", "Jung", "Kang", "Jo", "Yoon", "Jang", "Lim"], last: ["Minjun", "Seojun", "Doyun", "Jiho", "Jihun", "Seoyeon", "Seoyun", "Jiwoo", "Seohyun", "Minseo"] }, "TW": { first: ["Chen", "Lin", "Huang", "Chang", "Lee", "Wang", "Wu", "Liu", "Tsai", "Yang"], last: ["Zhiming", "Jianhong", "Junjie", "Yijun", "Shufen", "Meiling", "Yating", "Jiahao", "Zhihao", "Shuhui"] }, "HK": { first: ["Chan", "Lee", "Wong", "Cheung", "Lau", "Wang", "Ng", "Cheng", "Leung", "Ho"], last: ["Chiming", "Kayan", "Junjie", "Wingsze", "Kaming", "Meiling", "Kahao", "Winger", "Chihao", "Shukfan"] }, "US": { first: ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez"], last: ["James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph", "Thomas", "Christopher"] }, "UK": { first: ["Smith", "Jones", "Williams", "Taylor", "Brown", "Davies", "Evans", "Wilson", "Thomas", "Roberts"], last: ["Oliver", "Jack", "Harry", "George", "Noah", "Charlie", "Jacob", "Oscar", "William", "Leo"] }, "FR": { first: ["Martin", "Bernard", "Dubois", "Thomas", "Robert", "Richard", "Petit", "Durand", "Leroy", "Moreau"], last: ["Lucas", "Louis", "Gabriel", "Arthur", "Jules", "Hugo", "Leo", "Adam", "Raphael", "Paul"] }, "DE": { first: ["Mueller", "Schmidt", "Schneider", "Fischer", "Weber", "Meyer", "Wagner", "Becker", "Schulz", "Hoffmann"], last: ["Ben", "Paul", "Leon", "Noah", "Luis", "Finn", "Felix", "Jonas", "Maximilian", "Henry"] }, "IT": { first: ["Rossi", "Ferrari", "Russo", "Bianchi", "Romano", "Gallo", "Costa", "Fontana", "Conti", "Esposito"], last: ["Leonardo", "Francesco", "Alessandro", "Lorenzo", "Matteo", "Andrea", "Gabriele", "Marco", "Antonio", "Giuseppe"] }, "ES": { first: ["Garcia", "Rodriguez", "Gonzalez", "Fernandez", "Lopez", "Martinez", "Sanchez", "Perez", "Martin", "Gomez"], last: ["Antonio", "Jose", "Manuel", "Francisco", "David", "Juan", "Miguel", "Javier", "Rafael", "Carlos"] }, "BR": { first: ["Silva", "Santos", "Oliveira", "Souza", "Rodrigues", "Ferreira", "Alves", "Pereira", "Lima", "Gomes"], last: ["Miguel", "Arthur", "Heitor", "Pedro", "Davi", "Gabriel", "Bernardo", "Lucas", "Matheus", "Rafael"] }, "RU": { first: ["Ivanov", "Smirnov", "Kuznetsov", "Popov", "Vasiliev", "Petrov", "Sokolov", "Mikhailov", "Fedorov", "Morozov"], last: ["Alexander", "Dmitry", "Maxim", "Ivan", "Andrey", "Mikhail", "Artem", "Daniel", "Roman", "Sergey"] }, "IN": { first: ["Kumar", "Singh", "Sharma", "Patel", "Gupta", "Shah", "Verma", "Rao", "Reddy", "Joshi"], last: ["Aarav", "Vihaan", "Vivaan", "Aditya", "Arjun", "Reyansh", "Ayaan", "Sai", "Krishna", "Ishaan"] }, "AU": { first: ["Smith", "Jones", "Williams", "Brown", "Wilson", "Taylor", "Johnson", "White", "Anderson", "Thompson"], last: ["Oliver", "William", "Jack", "Noah", "Thomas", "James", "Lucas", "Henry", "Ethan", "Alexander"] }, "CA": { first: ["Smith", "Brown", "Tremblay", "Martin", "Roy", "Wilson", "MacDonald", "Taylor", "Campbell", "Anderson"], last: ["Liam", "Noah", "Oliver", "William", "James", "Benjamin", "Lucas", "Henry", "Theodore", "Jack"] }, "MX": { first: ["Garcia", "Rodriguez", "Martinez", "Lopez", "Gonzalez", "Perez", "Sanchez", "Ramirez", "Torres", "Flores"], last: ["Santiago", "Mateo", "Sebastian", "Leonardo", "Diego", "Daniel", "Gabriel", "Adrian", "David", "Alexander"] }, "TR": { first: ["Yilmaz", "Kaya", "Demir", "Sahin", "Celik", "Yildiz", "Erdogan", "Ozturk", "Aydin", "Ozdemir"], last: ["Yusuf", "Eymen", "Ömer", "Mustafa", "Ali", "Mehmet", "Ahmet", "Emir", "Hamza", "Ibrahim"] }, "SA": { first: ["Al-Saud", "Al-Sheikh", "Al-Rashid", "Al-Qahtani", "Al-Ghamdi", "Al-Zahrani", "Al-Dossari", "Al-Shammari", "Al-Otaibi", "Al-Harbi"], last: ["Mohammed", "Abdullah", "Ahmed", "Ali", "Omar", "Ibrahim", "Khalid", "Hassan", "Fahad", "Abdul"] }, "AR": { first: ["Gonzalez", "Rodriguez", "Garcia", "Fernandez", "Lopez", "Martinez", "Perez", "Romero", "Sanchez", "Diaz"], last: ["Mateo", "Thiago", "Benjamin", "Valentino", "Santiago", "Juan", "Lucas", "Martin", "Nicolas", "Joaquin"] }, "EG": { first: ["Mohamed", "Ahmed", "Mahmoud", "Ibrahim", "Ali", "Hassan", "Hussein", "Mostafa", "Kamal", "Samir"], last: ["Omar", "Youssef", "Adam", "Malik", "Zain", "Hamza", "Kareem", "Hassan", "Ali", "Ibrahim"] }, "NG": { first: ["Okafor", "Adebayo", "Okonkwo", "Eze", "Oluwaseun", "Adegoke", "Afolabi", "Ogunleye", "Adeniyi", "Adesina"], last: ["Oluwadamilare", "Oluwatobiloba", "Ayomide", "Temitope", "Oluwaseun", "Adebayo", "Chibuike", "Chisom", "Chidi", "Obinna"] }, "ID": { first: ["Wijaya", "Kusuma", "Suryanto", "Halim", "Santoso", "Tanaka", "Wibowo", "Susanto", "Hidayat", "Putra"], last: ["Muhammad", "Ahmad", "Abdul", "Aditya", "Budi", "Dimas", "Eko", "Fajar", "Gading", "Hadi"] }, "ZA": { first: ["Nkosi", "Van der Merwe", "Botha", "Mkhize", "Khumalo", "Pretorius", "Venter", "Ndlovu", "Fourie", "Nel"], last: ["Bandile", "Themba", "Sipho", "Thabo", "Jabu", "Mandla", "Blessing", "Gift", "Lucky", "Precious"] } }; // 电话号码格式配置 const phoneFormats = { "US": { format: "+1 (XXX) XXX-XXXX", areaCodeRanges: [[201, 989]] }, "CN": { format: "+86 1XX-XXXX-XXXX", mobilePrefix: ["30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "50", "51", "52", "53", "55", "56", "57", "58", "59", "66", "70", "71", "72", "73", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89"] }, "JP": { format: "+81 XX-XXXX-XXXX", mobilePrefix: ["70", "80", "90"] }, "KR": { format: "+82 10-XXXX-XXXX" }, "UK": { format: "+44 7XXX XXXXXX", mobilePrefix: ["7"] }, "FR": { format: "+33 6 XX XX XX XX", mobilePrefix: ["6", "7"] }, "DE": { format: "+49 15X XXXXXXXX", mobilePrefix: ["15", "16", "17"] }, "TW": { format: "+886 9XX-XXX-XXX" }, "HK": { format: "+852 XXXX XXXX", mobilePrefix: ["5", "6", "9"] }, "AU": { format: "+61 4XX XXX XXX", mobilePrefix: ["4"] }, "CA": { format: "+1 (XXX) XXX-XXXX", areaCodeRanges: [[204, 989]] }, "MX": { format: "+52 1XX XXX XXXX" }, "TR": { format: "+90 5XX XXX XXXX", mobilePrefix: ["5"] }, "SA": { format: "+966 5XX XXX XXXX", mobilePrefix: ["5"] }, "AR": { format: "+54 9XX XXXX-XXXX" }, "EG": { format: "+20 1XX XXX XXXX", mobilePrefix: ["1"] }, "NG": { format: "+234 8XX XXX XXXX", mobilePrefix: ["7", "8", "9"] }, "ID": { format: "+62 8XX-XXXX-XXXX", mobilePrefix: ["8"] }, "ZA": { format: "+27 8X XXX XXXX", mobilePrefix: ["6", "7", "8"] } }; // 工具函数 function getRandomLocation(country) { const coordsArray = countryCoordinates[country]; const randomCity = coordsArray[Math.floor(Math.random() * coordsArray.length)]; const lat = randomCity.lat + (Math.random() - 0.5) * 0.1; const lng = randomCity.lng + (Math.random() - 0.5) * 0.1; return { lat, lng }; } function getRandomName(country) { if (!namesByCountry[country]) { return null; } const names = namesByCountry[country]; const firstName = names.first[Math.floor(Math.random() * names.first.length)]; const lastName = names.last[Math.floor(Math.random() * names.last.length)]; return `${firstName} ${lastName}`; } function generateAreaCode(ranges) { const range = ranges[Math.floor(Math.random() * ranges.length)]; const [min, max] = range; return Math.floor(min + Math.random() * (max - min + 1)); } function getRandomPhoneNumber(country) { const format = phoneFormats[country] || phoneFormats["US"]; let phone = format.format; if (format.areaCodeRanges) { const areaCode = generateAreaCode(format.areaCodeRanges); phone = phone.replace("XXX", areaCode); phone = phone.replace(/X/g, () => Math.floor(Math.random() * 10)); } else if (format.mobilePrefix) { const prefix = format.mobilePrefix[Math.floor(Math.random() * format.mobilePrefix.length)]; // 先替换前缀 if (prefix.length === 2) { phone = phone.replace(/XX/, prefix); } else { phone = phone.replace(/X/, prefix); } // 然后替换剩余的X phone = phone.replace(/X/g, () => Math.floor(Math.random() * 10)); } else { phone = phone.replace(/X/g, () => Math.floor(Math.random() * 10)); } return phone; } function isValidAddress(data) { return data && data.address && data.address.house_number && data.address.road && (data.address.city || data.address.town); } // 处理CORS请求的headers const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, HEAD, POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type', }; // HTML 模板 const htmlContent = `<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>随机地址生成器</title> <script src="https://cdn.tailwindcss.com"></script> <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap" rel="stylesheet"> <script> tailwind.config = { theme: { extend: { animation: { 'gradient': 'gradient 8s linear infinite', }, keyframes: { gradient: { '0%, 100%': { 'background-size': '200% 200%', 'background-position': 'left center' }, '50%': { 'background-size': '200% 200%', 'background-position': 'right center' } } } } } } </script> </head> <body class="bg-gradient-to-br from-blue-50 via-white to-blue-50 text-gray-800 min-h-screen font-['Noto_Sans_SC']"> <!-- 头部 --> <header class="bg-gradient-to-r from-blue-500 via-sky-500 to-blue-500 animate-gradient w-full p-6 shadow-lg"> <div class="max-w-4xl mx-auto flex items-center justify-between"> <div class="flex items-center gap-3"> <img src="https://img.freepik.com/premium-vector/minimal-location-map-icon-logo-symbol-vector-design-transparent_965979-613.jpg?w=2000" alt="Logo" class="w-12 h-12 transform hover:scale-105 transition-transform"> <h1 class="text-2xl font-bold text-white">随机地址生成器</h1> </div> <a href="https://github.com/jiangnan1224/AddressGenerator/" target="_blank" class="flex items-center gap-2 text-white hover:text-gray-200 transition-colors"> <svg viewBox="0 0 16 16" class="w-6 h-6 fill-current" aria-hidden="true"> <path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path> </svg> <span class="font-medium">GitHub</span> </a> </div> </header> <!-- 主要内容 --> <main class="container mx-auto px-4 py-8 max-w-5xl"> <!-- 加载动画 --> <div id="loading" class="hidden fixed inset-0 bg-white bg-opacity-75 backdrop-blur-sm flex items-center justify-center z-50"> <div class="bg-white rounded-2xl p-8 flex flex-col items-center shadow-2xl"> <div class="animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-blue-500 mb-4"></div> <div class="text-gray-800 text-lg font-medium">正在加载...</div> </div> </div> <div id="copied" class="hidden fixed top-4 right-4 bg-green-500 text-white px-6 py-3 rounded-lg shadow-lg z-40 transform transition-transform duration-300"> 已复制到剪贴板! </div> <!-- 国家选择 --> <div class="bg-white rounded-2xl shadow-xl p-6 border border-gray-200 mb-8"> <div class="flex flex-col sm:flex-row items-start sm:items-center gap-4"> <div class="w-full sm:w-auto flex flex-col sm:flex-row items-start sm:items-center gap-2 flex-grow"> <label for="country" class="text-blue-600 font-bold whitespace-nowrap">选择国家/地区:</label> <select id="country" onchange="changeCountry(this.value)" class="w-full bg-gray-50 border border-gray-200 rounded-xl p-3 text-gray-800 focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all"> </select> </div> <button onclick="generateNewAddress(document.getElementById('country').value)" class="w-full sm:w-auto bg-gradient-to-r from-blue-500 to-sky-500 hover:from-blue-600 hover:to-sky-600 text-white font-bold py-3 px-6 rounded-xl transition-all transform hover:scale-105 hover:shadow-lg focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50"> 获取新地址 </button> </div> </div> <div class="grid grid-cols-1 lg:grid-cols-2 gap-8"> <!-- 左侧面板 --> <div class="space-y-6"> <!-- 信息卡片 --> <div class="bg-white rounded-2xl shadow-xl p-6 border border-gray-200"> <h2 class="text-xl font-bold mb-6 text-blue-600">个人信息</h2> <div class="space-y-4"> <div class="bg-gray-50 p-4 rounded-xl cursor-pointer hover:bg-gray-100 transition-all transform hover:scale-[1.02] hover:shadow-lg" onclick="copyToClipboard(this.querySelector('span').textContent)"> <strong class="text-blue-600">姓名:</strong><span id="name" class="ml-2"></span> </div> <div class="bg-gray-50 p-4 rounded-xl cursor-pointer hover:bg-gray-100 transition-all transform hover:scale-[1.02] hover:shadow-lg" onclick="copyToClipboard(this.querySelector('span').textContent)"> <strong class="text-blue-600">性别:</strong><span id="gender" class="ml-2"></span> </div> <div class="bg-gray-50 p-4 rounded-xl cursor-pointer hover:bg-gray-100 transition-all transform hover:scale-[1.02] hover:shadow-lg" onclick="copyToClipboard(this.querySelector('span').textContent)"> <strong class="text-blue-600">电话:</strong><span id="phone" class="ml-2"></span> </div> <div class="bg-gray-50 p-4 rounded-xl cursor-pointer hover:bg-gray-100 transition-all transform hover:scale-[1.02] hover:shadow-lg" onclick="copyToClipboard(this.querySelector('span').textContent)"> <strong class="text-blue-600">地址:</strong><span id="address" class="ml-2"></span> </div> </div> </div> <!-- 保存按钮 --> <button onclick="saveAddress()" class="w-full bg-gradient-to-r from-green-500 to-emerald-500 hover:from-green-600 hover:to-emerald-600 text-white font-bold py-3 px-6 rounded-xl transition-all transform hover:scale-105 hover:shadow-lg focus:ring-2 focus:ring-green-500 focus:ring-opacity-50"> 保存地址 </button> </div> <!-- 右侧面板 --> <div class="space-y-6"> <!-- 地图 --> <div class="bg-white rounded-2xl shadow-xl p-6 border border-gray-200"> <h2 class="text-xl font-bold mb-6 text-blue-600">地图预览</h2> <iframe id="map" class="w-full h-[400px] rounded-xl border border-gray-200"></iframe> </div> </div> </div> <!-- 已保存的地址表格 --> <div class="mt-8 bg-white rounded-2xl shadow-xl p-6 border border-gray-200"> <h2 class="text-xl font-bold mb-6 text-blue-600">已保存的地址</h2> <div class="overflow-x-auto"> <table class="w-full border-collapse" id="savedAddressesTable"> <thead> <tr class="bg-gradient-to-r from-blue-500 to-sky-500 text-white"> <th class="p-4 text-left rounded-tl-lg">姓名</th> <th class="p-4 text-left">性别</th> <th class="p-4 text-left">电话号码</th> <th class="p-4 text-left">地址</th> <th class="p-4 text-left">备注</th> <th class="p-4 text-left rounded-tr-lg">操作</th> </tr> </thead> <tbody></tbody> </table> </div> </div> </main> <!-- 页脚 --> <footer class="text-center py-8 text-gray-600 text-sm mt-8 bg-gray-50 border-t border-gray-200"> <p class="max-w-4xl mx-auto px-4"> All right reserved <a href="https://github.com/jiangnan1224/AddressGenerator/" target="_blank" class="inline-flex items-center hover:text-blue-600 transition-colors"> <img src="https://pic.imgdb.cn/item/66e7ab36d9c307b7e9cefd24.png" alt="GitHub" class="w-5 h-5 ml-1"> </a> </p> </footer> <script> // 国家数据 const countries = [ { name: "美国", code: "US" }, { name: "英国", code: "UK" }, { name: "法国", code: "FR" }, { name: "德国", code: "DE" }, { name: "中国", code: "CN" }, { name: "中国台湾", code: "TW" }, { name: "中国香港", code: "HK" }, { name: "日本", code: "JP" }, { name: "印度", code: "IN" }, { name: "澳大利亚", code: "AU" }, { name: "巴西", code: "BR" }, { name: "加拿大", code: "CA" }, { name: "俄罗斯", code: "RU" }, { name: "南非", code: "ZA" }, { name: "墨西哥", code: "MX" }, { name: "韩国", code: "KR" }, { name: "意大利", code: "IT" }, { name: "西班牙", code: "ES" }, { name: "土耳其", code: "TR" }, { name: "沙特阿拉伯", code: "SA" }, { name: "阿根廷", code: "AR" }, { name: "埃及", code: "EG" }, { name: "尼日利亚", code: "NG" }, { name: "印度尼西亚", code: "ID" } ]; // 初始化国家选择下拉框 function initCountrySelect() { const select = document.getElementById('country'); countries.forEach(country => { const option = document.createElement('option'); option.value = country.code; option.textContent = country.name; select.appendChild(option); }); } // 复制到剪贴板 function copyToClipboard(text) { navigator.clipboard.writeText(text).then(() => { const copied = document.getElementById('copied'); copied.classList.remove('hidden'); copied.classList.add('translate-y-0'); copied.classList.remove('translate-y-[-100%]'); setTimeout(() => { copied.classList.add('translate-y-[-100%]'); copied.classList.remove('translate-y-0'); setTimeout(() => { copied.classList.add('hidden'); }, 300); }, 2000); }); } // 显示/隐藏加载动画 function toggleLoading(show) { const loading = document.getElementById('loading'); if (show) { loading.classList.remove('hidden'); } else { loading.classList.add('hidden'); } } // 更改国家 function changeCountry(country) { toggleLoading(true); generateNewAddress(country); } // 保存地址 function saveAddress() { const note = prompt('请输入备注(可以留空)') || ''; const savedAddresses = JSON.parse(localStorage.getItem('savedAddresses') || '[]'); const newEntry = { note: note, name: document.getElementById('name').textContent, gender: document.getElementById('gender').textContent, phone: document.getElementById('phone').textContent, address: document.getElementById('address').textContent }; savedAddresses.push(newEntry); localStorage.setItem('savedAddresses', JSON.stringify(savedAddresses)); renderSavedAddresses(); } // 渲染保存的地址 function renderSavedAddresses() { const savedAddresses = JSON.parse(localStorage.getItem('savedAddresses') || '[]'); const tbody = document.querySelector('#savedAddressesTable tbody'); tbody.innerHTML = ''; savedAddresses.forEach((entry, index) => { const row = tbody.insertRow(); row.className = 'border-t border-gray-200 hover:bg-gray-50 transition-colors'; const cells = ['name', 'gender', 'phone', 'address', 'note', '']; cells.forEach((cell, i) => { const td = row.insertCell(); td.className = 'p-4'; if (i === cells.length - 1) { const deleteBtn = document.createElement('button'); deleteBtn.textContent = '删除'; deleteBtn.className = 'bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg transition-all transform hover:scale-105 focus:ring-2 focus:ring-red-500 focus:ring-opacity-50'; deleteBtn.onclick = () => { if (confirm('确定要删除这条记录吗?')) { savedAddresses.splice(index, 1); localStorage.setItem('savedAddresses', JSON.stringify(savedAddresses)); renderSavedAddresses(); } }; td.appendChild(deleteBtn); } else { td.textContent = entry[cell]; } }); }); } // 生成新地址 async function generateNewAddress(country) { if (!country) { country = document.getElementById('country').value; } toggleLoading(true); try { const response = await fetch(\`\${window.location.href}api?country=\${country}\`); const data = await response.json(); if (data.error) { alert(data.error); return; } document.getElementById('name').textContent = data.name; document.getElementById('gender').textContent = data.gender; document.getElementById('phone').textContent = data.phone; document.getElementById('address').textContent = data.address; // 更新地图 document.getElementById('map').src = \`https://www.google.com/maps?q=\${encodeURIComponent(data.address)}&output=embed\`; } catch (error) { console.error('Error fetching address:', error); alert('获取地址时发生错误,请重试'); } finally { toggleLoading(false); } } // 页面加载时初始化 window.onload = function() { initCountrySelect(); generateNewAddress(); renderSavedAddresses(); }; </script> </body> </html>`; async function handleRequest(request) { const url = new URL(request.url); const path = url.pathname; // 处理 API 请求 if (path === '/api') { // 原有的 API 处理逻辑 return handleApiRequest(request); } // 处理根路径请求,返回 HTML 页面 return new Response(htmlContent, { headers: { 'Content-Type': 'text/html;charset=UTF-8', ...corsHeaders } }); } // 将原有的处理逻辑移到单独的函数中 async function handleApiRequest(request) { if (request.method === 'OPTIONS') { return new Response(null, { headers: corsHeaders }); } if (request.method !== 'GET') { return new Response('Method not allowed', { status: 405 }); } const url = new URL(request.url); const country = url.searchParams.get('country') || 'US'; if (!countryCoordinates[country]) { return new Response(JSON.stringify({ error: 'Invalid country code' }), { status: 400, headers: { 'Content-Type': 'application/json', ...corsHeaders } }); } let attempts = 0; const maxAttempts = 20; while (attempts < maxAttempts) { try { const location = getRandomLocation(country); const apiUrl = `https://nominatim.openstreetmap.org/reverse?format=json&lat=${location.lat}&lon=${location.lng}&zoom=18&addressdetails=1`; const response = await fetch(apiUrl, { headers: { 'User-Agent': 'Cloudflare Worker Random Address Generator' } }); const data = await response.json(); if (isValidAddress(data)) { let city = data.address.city || data.address.town || ''; city = city.split(';')[0].trim(); const address = `${data.address.house_number} ${data.address.road}, ${city}, ${data.address.postcode || ''}, ${country}`.replace(/\s+/g, ' ').trim(); const name = getRandomName(country); const gender = Math.random() > 0.5 ? 'Male' : 'Female'; const phone = getRandomPhoneNumber(country); const result = { name, gender, phone, address, coordinates: { lat: location.lat, lng: location.lng } }; return new Response(JSON.stringify(result), { headers: { 'Content-Type': 'application/json', ...corsHeaders } }); } attempts++; if (attempts < maxAttempts) { await new Promise(resolve => setTimeout(resolve, 100)); } } catch (error) { attempts++; if (attempts < maxAttempts) { await new Promise(resolve => setTimeout(resolve, 100)); } } } return new Response(JSON.stringify({ error: 'Failed to generate valid address after multiple attempts' }), { status: 500, headers: { 'Content-Type': 'application/json', ...corsHeaders } }); } // 注册事件监听器 addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)); }); {dotted startColor="#ff6c6c" endColor="#1989fa"/}2、修改后的代码,各有所好,当然也可以找一下其它人修改的代码2025年07月16日更新,界面调整,添加多个国家和地区// 国家坐标数据 const countryCoordinates = { "US": [{ lat: 37.7749, lng: -122.4194 }, { lat: 34.0522, lng: -118.2437 }, { lat: 32.7767, lng: -96.7970 }, { lat: 41.8781, lng: -87.6298 }, { lat: 29.7604, lng: -95.3698 }, { lat: 33.4484, lng: -112.0740 }, { lat: 39.9526, lng: -75.1652 }, { lat: 29.4241, lng: -98.4936 }, { lat: 32.7157, lng: -117.1611 }, { lat: 47.6062, lng: -122.3321 }], "NY US": [{ lat: 40.7128, lng: -74.0060 }], "California US": [{ lat: 34.0522, lng: -118.2437 }], "Texas US": [{ lat: 32.7767, lng: -96.7970 }], "CA US": [{ lat: 37.3382, lng: -121.8863 }], "Illinois US": [{ lat: 41.8781, lng: -87.6298 }], // 添加的城市坐标:休斯敦、菲尼克斯、费城、圣安东尼奥、圣地亚哥、西雅图 "TX US": [{ lat: 29.7604, lng: -95.3698 }], "Arizona US": [{ lat: 33.4484, lng: -112.0740 }], "Pennsylvania US": [{ lat: 39.9526, lng: -75.1652 }], "Tx US": [{ lat: 29.4241, lng: -98.4936 }], "Ca US": [{ lat: 32.7157, lng: -117.1611 }], "Washington US": [{ lat: 47.6062, lng: -122.3321 }], "UK": [{ lat: 51.5074, lng: -0.1278 }, { lat: 53.4808, lng: -2.2426 }], "FR": [{ lat: 48.8566, lng: 2.3522 }, { lat: 45.7640, lng: 4.8357 }, { lat: 43.2965, lng: 5.3698 }], "DE": [{ lat: 52.5200, lng: 13.4050 }, { lat: 48.1351, lng: 11.5820 }], "CN": [{ lat: 39.9042, lng: 116.4074 }, { lat: 31.2304, lng: 121.4737 }], "TW": [{ lat: 25.0330, lng: 121.5654 }, { lat: 22.6273, lng: 120.3014 }], "HK": [{ lat: 22.3193, lng: 114.1694 },{ lat: 22.3964, lng: 114.1095 }], "JP": [{ lat: 35.6895, lng: 139.6917 }, { lat: 34.6937, lng: 135.5023 }], "IN": [{ lat: 28.6139, lng: 77.2090 }, { lat: 19.0760, lng: 72.8777 }], "AU": [{ lat: -33.8688, lng: 151.2093 }, { lat: -37.8136, lng: 144.9631 }], "BR": [{ lat: -23.5505, lng: -46.6333 }, { lat: -22.9068, lng: -43.1729 }], "CA": [{ lat: 43.651070, lng: -79.347015 }, { lat: 45.501690, lng: -73.567253 }], "RU": [{ lat: 55.7558, lng: 37.6173 }, { lat: 59.9343, lng: 30.3351 }], "ZA": [{ lat: -33.9249, lng: 18.4241 }, { lat: -26.2041, lng: 28.0473 }], "MX": [{ lat: 19.4326, lng: -99.1332 }, { lat: 20.6597, lng: -103.3496 }], "KR": [{ lat: 37.5665, lng: 126.9780 }, { lat: 35.1796, lng: 129.0756 }], "IT": [{ lat: 41.9028, lng: 12.4964 }, { lat: 45.4642, lng: 9.1900 }], "ES": [{ lat: 40.4168, lng: -3.7038 }, { lat: 41.3851, lng: 2.1734 }], "TR": [{ lat: 41.0082, lng: 28.9784 }, { lat: 39.9334, lng: 32.8597 }], "SA": [{ lat: 24.7136, lng: 46.6753 }, { lat: 21.3891, lng: 39.8579 }], "AR": [{ lat: -34.6037, lng: -58.3816 }, { lat: -31.4201, lng: -64.1888 }], "EG": [{ lat: 30.0444, lng: 31.2357 }, { lat: 31.2156, lng: 29.9553 }], "NG": [{ lat: 6.5244, lng: 3.3792 }, { lat: 9.0579, lng: 7.4951 }], "ID": [{ lat: -6.2088, lng: 106.8456 }, { lat: -7.7956, lng: 110.3695 }], "VN": [{ lat: 21.0285, lng: 105.8048 }, { lat: 10.7626, lng: 106.6602 }], // 添加越南坐标数据 // 新增城市坐标 "Berlin DE": [{ lat: 52.5200, lng: 13.4050 }], "Bavaria DE": [{ lat: 48.1351, lng: 11.5820 }], "Île-de-France FR": [{ lat: 48.8566, lng: 2.3522 }], "Provence-Alpes-Côte d'Azur FR": [{ lat: 43.2965, lng: 5.3698 }], "London UK": [{ lat: 51.5074, lng: -0.1278 }], "Seoul KR": [{ lat: 37.5665, lng: 126.9780 }], "Ontario CA": [{ lat: 43.651070, lng: -79.347015 }], "Comunidad de Madrid ES": [{ lat: 40.4168, lng: -3.7038 }], "Cataluña ES": [{ lat: 41.3851, lng: 2.1734 }], "Tokyo JP": [{ lat: 35.6895, lng: 139.6917 }], "Osaka JP": [{ lat: 34.6937, lng: 135.5023 }], }; // 姓名数据 const namesByCountry = { "US": { first: ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez"], last: ["James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph", "Thomas", "Christopher"] }, "CN": { first: ["李", "王", "张", "刘", "陈", "杨", "黄", "赵", "吴", "周", "孙", "苏", "马", "朱", "候", "郭", "黑", "高", "林", "钱", "冯", "卫", "蒋", "许", "吕", "施", "曹", "严", "魏", "陶", "方", "雷"], last: ["力", "斌", "那", "真", "杰", "京", "丽", "晴", "来", "东", "勇", "仕", "云", "洁", "山", "伟", "明", "亮", "刚", "飞", "英", "兴", "浩", "曙光", "平", "志远", "志珍", "第一", "建国", "玉仙", "现红", "瑞山", "一山", "新丽", "思思", "青凤", "秀美"] }, "JP": { first: ["Sato", "Suzuki", "Takahashi", "Tanaka", "Watanabe", "Ito", "Yamamoto", "Nakamura", "Kobayashi", "Kato"], last: ["Shota", "Ren", "Hina", "Yui", "Hiroto", "Sota", "Yota", "Misaki", "Nanami", "Yuto"] }, "KR": { first: ["Kim", "Lee", "Park", "Choi", "Jung", "Kang", "Jo", "Yoon", "Jang", "Lim"], last: ["Minjun", "Seojun", "Doyun", "Jiho", "Jihun", "Seoyeon", "Seoyun", "Jiwoo", "Seohyun", "Minseo"] }, "TW": { first: ["Chen", "Lin", "Huang", "Chang", "Lee", "Wang", "Wu", "Liu", "Tsai", "Yang"], last: ["Zhiming", "Jianhong", "Junjie", "Yijun", "Shufen", "Meiling", "Yating", "Jiahao", "Zhihao", "Shuhui"] }, "HK": { first: ["Chan", "Lee", "Wong", "Cheung", "Lau", "Wang", "Ng", "Cheng", "Leung", "Ho"], last: ["Chiming", "Kayan", "Junjie", "Wingsze", "Kaming", "Meiling", "Kahao", "Winger", "Chihao", "Shukfan"] }, "UK": { first: ["Smith", "Jones", "Williams", "Taylor", "Brown", "Davies", "Evans", "Wilson", "Thomas", "Roberts"], last: ["Oliver", "Jack", "Harry", "George", "Noah", "Charlie", "Jacob", "Oscar", "William", "Leo"] }, "FR": { first: ["Martin", "Bernard", "Dubois", "Thomas", "Robert", "Richard", "Petit", "Durand", "Leroy", "Moreau"], last: ["Lucas", "Louis", "Gabriel", "Arthur", "Jules", "Hugo", "Leo", "Adam", "Raphael", "Paul"] }, "DE": { first: ["Mueller", "Schmidt", "Schneider", "Fischer", "Weber", "Meyer", "Wagner", "Becker", "Schulz", "Hoffmann"], last: ["Ben", "Paul", "Leon", "Noah", "Luis", "Finn", "Felix", "Jonas", "Maximilian", "Henry"] }, "IT": { first: ["Rossi", "Ferrari", "Russo", "Bianchi", "Romano", "Gallo", "Costa", "Fontana", "Conti", "Esposito"], last: ["Leonardo", "Francesco", "Alessandro", "Lorenzo", "Matteo", "Andrea", "Gabriele", "Marco", "Antonio", "Giuseppe"] }, "ES": { first: ["Garcia", "Rodriguez", "Gonzalez", "Fernandez", "Lopez", "Martinez", "Sanchez", "Perez", "Martin", "Gomez"], last: ["Antonio", "Jose", "Manuel", "Francisco", "David", "Juan", "Miguel", "Javier", "Rafael", "Carlos"] }, "BR": { first: ["Silva", "Santos", "Oliveira", "Souza", "Rodrigues", "Ferreira", "Alves", "Pereira", "Lima", "Gomes"], last: ["Miguel", "Arthur", "Heitor", "Pedro", "Davi", "Gabriel", "Bernardo", "Lucas", "Matheus", "Rafael"] }, "RU": { first: ["Ivanov", "Smirnov", "Kuznetsov", "Popov", "Vasiliev", "Petrov", "Sokolov", "Mikhailov", "Fedorov", "Morozov"], last: ["Alexander", "Dmitry", "Maxim", "Ivan", "Andrey", "Mikhail", "Artem", "Daniel", "Roman", "Sergey"] }, "IN": { first: ["Kumar", "Singh", "Sharma", "Patel", "Gupta", "Shah", "Verma", "Rao", "Reddy", "Joshi"], last: ["Aarav", "Vihaan", "Vivaan", "Aditya", "Arjun", "Reyansh", "Ayaan", "Sai", "Krishna", "Ishaan"] }, "AU": { first: ["Smith", "Jones", "Williams", "Brown", "Wilson", "Taylor", "Johnson", "White", "Anderson", "Thompson"], last: ["Oliver", "William", "Jack", "Noah", "Thomas", "James", "Lucas", "Henry", "Ethan", "Alexander"] }, "CA": { first: ["Smith", "Brown", "Tremblay", "Martin", "Roy", "Wilson", "MacDonald", "Taylor", "Campbell", "Anderson"], last: ["Liam", "Noah", "Oliver", "William", "James", "Benjamin", "Lucas", "Henry", "Theodore", "Jack"] }, "MX": { first: ["Garcia", "Rodriguez", "Martinez", "Lopez", "Gonzalez", "Perez", "Sanchez", "Ramirez", "Torres", "Flores"], last: ["Santiago", "Mateo", "Sebastian", "Leonardo", "Diego", "Daniel", "Gabriel", "Adrian", "David", "Alexander"] }, "TR": { first: ["Yilmaz", "Kaya", "Demir", "Sahin", "Celik", "Yildiz", "Erdogan", "Ozturk", "Aydin", "Ozdemir"], last: ["Yusuf", "Eymen", "Ömer", "Mustafa", "Ali", "Mehmet", "Ahmet", "Emir", "Hamza", "Ibrahim"] }, "SA": { first: ["Al-Saud", "Al-Sheikh", "Al-Rashid", "Al-Qahtani", "Al-Ghamdi", "Al-Zahrani", "Al-Dossari", "Al-Shammari", "Al-Otaibi", "Al-Harbi"], last: ["Mohammed", "Abdullah", "Ahmed", "Ali", "Omar", "Ibrahim", "Khalid", "Hassan", "Fahad", "Abdul"] }, "AR": { first: ["Gonzalez", "Rodriguez", "Garcia", "Fernandez", "Lopez", "Martinez", "Perez", "Romero", "Sanchez", "Diaz"], last: ["Mateo", "Thiago", "Benjamin", "Valentino", "Santiago", "Juan", "Lucas", "Martin", "Nicolas", "Joaquin"] }, "EG": { first: ["Mohamed", "Ahmed", "Mahmoud", "Ibrahim", "Ali", "Hassan", "Hussein", "Mostafa", "Kamal", "Samir"], last: ["Omar", "Youssef", "Adam", "Malik", "Zain", "Hamza", "Kareem", "Hassan", "Ali", "Ibrahim"] }, "NG": { first: ["Okafor", "Adebayo", "Okonkwo", "Eze", "Oluwaseun", "Adegoke", "Afolabi", "Ogunleye", "Adeniyi", "Adesina"], last: ["Oluwadamilare", "Oluwatobiloba", "Ayomide", "Temitope", "Oluwaseun", "Adebayo", "Chibuike", "Chisom", "Chidi", "Obinna"] }, "ID": { first: ["Wijaya", "Kusuma", "Suryanto", "Halim", "Santoso", "Tanaka", "Wibowo", "Susanto", "Hidayat", "Putra"], last: ["Muhammad", "Ahmad", "Abdul", "Aditya", "Budi", "Dimas", "Eko", "Fajar", "Gading", "Hadi"] }, "ZA": { first: ["Nkosi", "Van der Merwe", "Botha", "Mkhize", "Khumalo", "Pretorius", "Venter", "Ndlovu", "Fourie", "Nel"], last: ["Bandile", "Themba", "Sipho", "Thabo", "Jabu", "Mandla", "Blessing", "Gift", "Lucky", "Precious"] }, "VN": { first: ["Nguyen", "Tran", "Le", "Pham", "Hoang", "Vu", "Do", "Dao", "Bui", "Dang"], last: ["Van", "Minh", "Thanh", "Ngoc", "Huu", "Quoc", "Xuan", "Duc", "Tuan", "Khanh"] } }; // 电话号码格式配置 const phoneFormats = { "US": { format: "+1 (XXX) XXX-XXXX", areaCodeRanges: [[201, 989]] }, "CN": { format: "+86 1XX-XXXX-XXXX", mobilePrefix: ["30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "50", "51", "52", "53", "55", "56", "57", "58", "59", "66", "70", "71", "72", "73", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89"] }, "JP": { format: "+81 XX-XXXX-XXXX", mobilePrefix: ["70", "80", "90"] }, "KR": { format: "+82 10-XXXX-XXXX" }, "UK": { format: "+44 7XXX XXXXXX", mobilePrefix: ["7"] }, "FR": { format: "+33 6 XX XX XX XX", mobilePrefix: ["6", "7"] }, "DE": { format: "+49 15X XXXXXXXX", mobilePrefix: ["15", "16", "17"] }, "TW": { format: "+886 9XX-XXX-XXX" }, "HK": { format: "+852 XXXX XXXX", mobilePrefix: ["5", "6", "9"] }, "AU": { format: "+61 4XX XXX XXX", mobilePrefix: ["4"] }, "CA": { format: "+1 (XXX) XXX-XXXX", areaCodeRanges: [[204, 989]] }, "MX": { format: "+52 1XX XXX XXXX" }, "TR": { format: "+90 5XX XXX XXXX", mobilePrefix: ["5"] }, "SA": { format: "+966 5XX XXX XXXX", mobilePrefix: ["5"] }, "AR": { format: "+54 9XX XXXX-XXXX" }, "EG": { format: "+20 1XX XXX XXXX", mobilePrefix: ["1"] }, "NG": { format: "+234 8XX XXX XXXX", mobilePrefix: ["7", "8", "9"] }, "ID": { format: "+62 8XX-XXXX-XXXX", mobilePrefix: ["8"] }, "ZA": { format: "+27 8X XXX XXXX", mobilePrefix: ["6", "7", "8"] }, "VN": { format: "+84 9X XXX XXXX", mobilePrefix: ["9", "8"] } }; // 新增加的所有美国地区别名都指向同一个 US 数据 namesByCountry["NY US"] = namesByCountry["US"]; namesByCountry["California US"] = namesByCountry["US"]; namesByCountry["Texas US"] = namesByCountry["US"]; namesByCountry["CA US"] = namesByCountry["US"]; namesByCountry["Illinois US"] = namesByCountry["US"]; namesByCountry["TX US"] = namesByCountry["US"]; namesByCountry["Arizona US"] = namesByCountry["US"]; namesByCountry["Pennsylvania US"] = namesByCountry["US"]; namesByCountry["Tx US"] = namesByCountry["US"]; namesByCountry["Ca US"] = namesByCountry["US"]; namesByCountry["Washington US"] = namesByCountry["US"]; namesByCountry["Berlin DE"] = namesByCountry["DE"]; namesByCountry["Bavaria DE"] = namesByCountry["DE"]; namesByCountry["Île-de-France FR"] = namesByCountry["FR"]; namesByCountry["Provence-Alpes-Côte d'Azur FR"] = namesByCountry["FR"]; namesByCountry["London UK"] = namesByCountry["UK"]; namesByCountry["Seoul KR"] = namesByCountry["KR"]; namesByCountry["Ontario CA"] = namesByCountry["CA"]; namesByCountry["Comunidad de Madrid ES"] = namesByCountry["ES"]; namesByCountry["Cataluña ES"] = namesByCountry["ES"]; namesByCountry["Tokyo JP"] = namesByCountry["JP"]; namesByCountry["Osaka JP"] = namesByCountry["JP"]; // 新增加的美国所有电话别名都指向同一个 US 数据 phoneFormats["NY US"] = phoneFormats["US"]; phoneFormats["California US"] = phoneFormats["US"]; phoneFormats["Texas US"] = phoneFormats["US"]; phoneFormats["CA US"] = phoneFormats["US"]; phoneFormats["Illinois US"] = phoneFormats["US"]; phoneFormats["TX US"] = phoneFormats["US"]; phoneFormats["Arizona US"] = phoneFormats["US"]; phoneFormats["Pennsylvania US"] = phoneFormats["US"]; phoneFormats["Tx US"] = phoneFormats["US"]; phoneFormats["Ca US"] = phoneFormats["US"]; phoneFormats["Washington US"] = phoneFormats["US"]; phoneFormats["Berlin DE"] = phoneFormats["DE"]; phoneFormats["Bavaria DE"] = phoneFormats["DE"]; phoneFormats["Île-de-France FR"] = phoneFormats["FR"]; phoneFormats["Provence-Alpes-Côte d'Azur FR"] = phoneFormats["FR"]; phoneFormats["London UK"] = phoneFormats["UK"]; phoneFormats["Seoul KR"] = phoneFormats["KR"]; phoneFormats["Ontario CA"] = phoneFormats["CA"]; phoneFormats["Comunidad de Madrid ES"] = phoneFormats["ES"]; phoneFormats["Cataluña ES"] = phoneFormats["ES"]; phoneFormats["Tokyo JP"] = phoneFormats["JP"]; phoneFormats["Osaka JP"] = phoneFormats["JP"]; // 工具函数 function getRandomLocation(country) { const coordsArray = countryCoordinates[country]; const randomCity = coordsArray[Math.floor(Math.random() * coordsArray.length)]; const lat = randomCity.lat + (Math.random() - 0.5) * 0.1; const lng = randomCity.lng + (Math.random() - 0.5) * 0.1; return { lat, lng }; } function getRandomName(country) { if (!namesByCountry[country]) { return null; } const names = namesByCountry[country]; const firstName = names.first[Math.floor(Math.random() * names.first.length)]; const lastName = names.last[Math.floor(Math.random() * names.last.length)]; return `${firstName} ${lastName}`; } function generateAreaCode(ranges) { const range = ranges[Math.floor(Math.random() * ranges.length)]; const [min, max] = range; return Math.floor(min + Math.random() * (max - min + 1)); } function getRandomPhoneNumber(country) { const format = phoneFormats[country] || phoneFormats["US"]; let phone = format.format; if (format.areaCodeRanges) { const areaCode = generateAreaCode(format.areaCodeRanges); phone = phone.replace("XXX", areaCode); phone = phone.replace(/X/g, () => Math.floor(Math.random() * 10)); } else if (format.mobilePrefix) { const prefix = format.mobilePrefix[Math.floor(Math.random() * format.mobilePrefix.length)]; // 先替换前缀 if (prefix.length === 2) { phone = phone.replace(/XX/, prefix); } else { phone = phone.replace(/X/, prefix); } // 然后替换剩余的X phone = phone.replace(/X/g, () => Math.floor(Math.random() * 10)); } else { phone = phone.replace(/X/g, () => Math.floor(Math.random() * 10)); } return phone; } function isValidAddress(data) { return data && data.address && data.address.house_number && data.address.road && (data.address.city || data.address.town); } // 处理CORS请求的headers const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, HEAD, POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type', }; // HTML 模板 const htmlContent = `<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>随机地址生成器</title> <script src="https://cdn.tailwindcss.com"></script> <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap" rel="stylesheet"> <script> tailwind.config = { theme: { extend: { animation: { 'gradient': 'gradient 8s linear infinite', }, keyframes: { gradient: { '0%, 100%': { 'background-size': '200% 200%', 'background-position': 'left center' }, '50%': { 'background-size': '200% 200%', 'background-position': 'right center' } } } } } } </script> </head> <link rel="shortcut icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2280%22>🌐</text></svg>"> <body class="bg-gradient-to-br from-blue-50 via-white to-blue-50 text-gray-800 min-h-screen font-['Noto_Sans_SC']"> <!-- 头部 --> <header class="bg-gradient-to-r from-blue-500 via-sky-500 to-blue-500 animate-gradient w-full p-6 shadow-lg"> <div class="max-w-4xl mx-auto flex items-center justify-between"> <div class="flex items-center gap-3"> <h1 class="text-2xl font-bold text-white">随机地址生成器</h1> </div> <div class="flex items-center gap-3"> <a href="/" target="_blank" class="flex items-center gap-2 text-white hover:text-gray-200 transition-colors"> <svg viewBox="0 0 16 16" class="w-6 h-6 fill-current" aria-hidden="true"> <img src="https://img.freepik.com/premium-vector/minimal-location-map-icon-logo-symbol-vector-design-transparent_965979-613.jpg?w=2000" alt="Logo" class="w-8 h-8 transform hover:scale-105 transition-transform"> </svg> </a> <a href="/about" class="flex items-center gap-2 text-white hover:text-gray-200 transition-colors"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/> <path d="m8.93 6.588-2.29.287-.082.38.45.083c.296.07.366.177.246.475l-.136.283-.14.064c-.296.136-.494.397-.56.745-.107 1.044.44 1.43 1.234 1.43.46.002.832-.166 1.06-.432.246-.28.334-.677.256-1.176-.09-.564-.426-.977-.977-.977-.642 0-.962.514-.962 1.176 0 .242.047.466.126.652.126.309.34.564.626.652.296.09.662.034.962-.126.296-.16.494-.432.56-.744.107-.564-.246-1.098-.832-1.098-.426 0-.764.29-.962.652-.107.19-.186.408-.246.652-.06.244-.082.49-.082.744 0 1.134.732 2.042 1.634 2.042.902 0 1.634-.908 1.634-2.042 0-1.134-.732-2.042-1.634-2.042zm-.634 5.5c-.344 0-.6-.256-.6-.588 0-.332.256-.588.6-.588.344 0 .6.256.6.588 0 .332-.256.588-.6.588z"/> </svg> <span class="font-medium">关于</span> </a> </div> </div> </header> <!-- 关于页面内容 --> <div id="about" class="hidden max-w-4xl mx-auto px-4 py-8"> <div class="bg-white rounded-2xl shadow-xl p-8 border border-gray-200"> <h2 class="text-2xl font-bold mb-6 text-blue-600">关于本项目</h2> <div class="prose max-w-none"> <p class="mb-4">随机地址生成器是一个实用工具,可以帮助用户快速生成大多数常用国家和地区的随机地址信息【根据需要,国家和地区不断完善中】。该工具适用于测试、开发以及其他需要模拟地址数据的场景。</p> <p class="mb-4">本项目使用 Cloudflare Workers 技术构建,结合 OpenStreetMap 的地理编码服务,能够实时生成准确的地址信息。通过简单的界面操作,您可以轻松获取不同国家的地址、电话号码和个人信息。</p> <h3 class="text-xl font-semibold mt-6 mb-3 text-blue-600">主要功能</h3> <ul class="list-disc pl-6 space-y-2 mb-4"> <li>支持多个国家和地区的地址生成</li> <li>自动生成姓名、性别、电话号码等个人信息</li> <li>技术有限,英国、日本等一些国家的邮编,『地址中倒数第2项提取』</li> <li>集成地图预览功能</li> <li>支持保存常用地址</li> <li>响应式设计适配各种设备</li> </ul> <h3 class="text-xl font-semibold mt-6 mb-3 text-blue-600">技术特点</h3> <ul class="list-disc pl-6 space-y-2 mb-4"> <li>基于 Cloudflare Workers 构建,实现无服务器架构</li> <li>使用 Tailwind CSS 实现现代化 UI 设计</li> <li>集成 OpenStreetMap 地理编码 API</li> <li>前端完全静态化,无需后端数据库支持</li> <li>本地存储保存历史记录</li> </ul> <h3 class="text-xl font-semibold mt-6 mb-3 text-blue-600">使用说明</h3> <p class="mb-4">选择国家或地区后点击“获取新地址”按钮即可生成随机地址信息。您可以通过点击各项信息将其复制到剪贴板,也可以点击“保存地址”按钮将当前地址保存到本地浏览器。</p> <p class="mb-4">在保存的地址列表中,您可以查看所有已保存的地址,并可随时删除不需要的记录。</p> <h3 class="text-xl font-semibold mt-6 mb-3 text-blue-600">联系方式</h3> <p>如有任何问题或建议,请访问我们的<a href="https://www.199881.xyz/" target="_blank" class="text-blue-600 hover:underline">官方网站</a>或通过 GitHub 联系我们。</p> </div> </div> </div> <!-- 主要内容 --> <main id="main-content" class="container mx-auto px-4 py-8 max-w-5xl"> <!-- 加载动画 --> <div id="loading" class="hidden fixed inset-0 bg-white bg-opacity-75 backdrop-blur-sm flex items-center justify-center z-50"> <div class="bg-white rounded-2xl p-8 flex flex-col items-center shadow-2xl"> <div class="animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-blue-500 mb-4"></div> <div class="text-gray-800 text-lg font-medium">正在加载...</div> </div> </div> <div id="copied" class="hidden fixed top-4 right-4 bg-green-500 text-white px-6 py-3 rounded-lg shadow-lg z-40 transform transition-transform duration-300"> 已复制到剪贴板! </div> <!-- 国家选择 --> <div class="bg-white rounded-2xl shadow-xl p-6 border border-gray-200 mb-8"> <div class="flex flex-col sm:flex-row items-start sm:items-center gap-4"> <div class="w-full sm:w-auto flex flex-col sm:flex-row items-start sm:items-center gap-2 flex-grow"> <label for="country" class="text-blue-600 font-bold whitespace-nowrap">选择国家/地区:</label> <select id="country" onchange="changeCountry(this.value)" class="w-full bg-gray-50 border border-gray-200 rounded-xl p-3 text-gray-800 focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all"> </select> </div> <button onclick="generateNewAddress(document.getElementById('country').value)" class="w-full sm:w-auto bg-gradient-to-r from-blue-500 to-sky-500 hover:from-blue-600 hover:to-sky-600 text-white font-bold py-3 px-6 rounded-xl transition-all transform hover:scale-105 hover:shadow-lg focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50"> 获取新地址 </button> </div> </div> <div class="grid grid-cols-1 lg:grid-cols-2 gap-8"> <!-- 左侧面板 --> <div class="space-y-2"> <!-- 信息卡片 --> <div class="bg-white rounded-2xl shadow-xl p-6 border border-gray-200"> <h2 class="text-xl font-bold mb-6 text-blue-600">个人信息</h2> <div class="space-y-2"> <div class="bg-gray-50 p-4 rounded-xl cursor-pointer hover:bg-gray-100 transition-all transform hover:scale-[1.02] hover:shadow-lg" onclick="copyToClipboard(this.querySelector('span').textContent)"> <strong class="text-blue-600">姓名:</strong><span id="name" class="ml-2"></span> </div> <div class="bg-gray-50 p-4 rounded-xl cursor-pointer hover:bg-gray-100 transition-all transform hover:scale-[1.02] hover:shadow-lg" onclick="copyToClipboard(this.querySelector('span').textContent)"> <strong class="text-blue-600">性别:</strong><span id="gender" class="ml-2"></span> </div> <div class="bg-gray-50 p-4 rounded-xl cursor-pointer hover:bg-gray-100 transition-all transform hover:scale-[1.02] hover:shadow-lg" onclick="copyToClipboard(this.querySelector('span').textContent)"> <strong class="text-blue-600">电话:</strong><span id="phone" class="ml-2"></span> </div> <div class="bg-gray-50 p-4 rounded-xl cursor-pointer hover:bg-gray-100 transition-all transform hover:scale-[1.02] hover:shadow-lg" onclick="copyToClipboard(this.querySelector('span').textContent)"> <strong class="text-blue-600">邮编:</strong><span id="postcode" class="ml-2"></span> </div> <div class="bg-gray-50 p-4 rounded-xl cursor-pointer hover:bg-gray-100 transition-all transform hover:scale-[1.02] hover:shadow-lg" onclick="copyToClipboard(this.querySelector('span').textContent)"> <strong class="text-blue-600">地址:</strong><span id="address" class="ml-2"></span> </div> </div> </div> <!-- 保存按钮 --> <button onclick="saveAddress()" class="w-full bg-gradient-to-r from-green-500 to-emerald-500 hover:from-green-600 hover:to-emerald-600 text-white font-bold py-3 px-6 rounded-xl transition-all transform hover:scale-105 hover:shadow-lg focus:ring-2 focus:ring-green-500 focus:ring-opacity-50"> 保存地址 </button> </div> <!-- 右侧面板 --> <div class="space-y-2"> <!-- 地图 --> <div class="bg-white rounded-2xl shadow-xl p-6 border border-gray-200"> <h2 class="text-xl font-bold mb-6 text-blue-600">地图预览</h2> <iframe id="map" class="w-full h-[372px] rounded-xl border border-gray-200"></iframe> </div> </div> </div> <!-- 已保存的地址表格 --> <div class="mt-8 bg-white rounded-2xl shadow-xl p-6 border border-gray-200"> <h2 class="text-xl font-bold mb-6 text-blue-600">已保存的地址</h2> <div class="overflow-x-auto"> <table class="w-full border-collapse" id="savedAddressesTable"> <thead> <tr class="bg-gradient-to-r from-blue-500 to-sky-500 text-white"> <th class="p-4 text-left rounded-tl-lg">姓名</th> <th class="p-4 text-left">性别</th> <th class="p-4 text-left">电话</th> <th class="p-4 text-left">地址</th> <th class="p-4 text-left">备注</th> <th class="p-4 text-left rounded-tr-lg">操作</th> </tr> </thead> <tbody></tbody> </table> </div> </div> </main> <!-- 页脚 --> <footer class="text-center py-8 text-gray-600 text-sm mt-8 bg-gray-50 border-t border-gray-200"> <p class="max-w-4xl mx-auto px-4"> 总访问量 <span id="busuanzi_site_pv"></span> 次 | <span id="timeDate">载入天数...</span> | <a href="https://boke.199881.xyz/" target="_blank"> <span style="color: blue;">博客 | <a href="https://www.199881.xyz/" target="_blank"> <span style="color: green;">导航 <a href="https://github.com/jiangnan1224/AddressGenerator/" target="_blank" class="inline-flex items-center hover:text-blue-600 transition-colors"> <img src="https://pic.imgdb.cn/item/66e7ab36d9c307b7e9cefd24.png" alt="GitHub" class="w-5 h-5 ml-1"> </a> <script language="javascript"> var now = new Date(); function createtime(){ var grt= new Date("04/23/2025 00:00:00");/*---这里是网站的启用时间--*/ now.setTime(now.getTime()+250); days = (now - grt ) / 1000 / 60 / 60 / 24; dnum = Math.floor(days); document.getElementById("timeDate").innerHTML = "运行"+dnum+"天"; } setInterval("createtime()",250); </script> <script defer src="https://bsz.211119.xyz/js"></script> </p> </footer> <script> // 国家数据 const countries = [ { name: "美国", code: "US" }, { name: "美国纽约", code: "NY US" }, { name: "美国洛杉矶", code: "California US" }, { name: "美国达拉斯", code: "Texas US" }, { name: "美国圣何塞", code: "CA US" }, { name: "美国芝加哥", code: "Illinois US" }, { name: "美国休斯敦", code: "TX US" }, { name: "美国菲尼克斯", code: "Arizona US" }, { name: "美国费城", code: "Pennsylvania US" }, { name: "美国圣安东尼奥", code: "Tx US" }, { name: "美国圣地亚哥", code: "Ca US" }, { name: "美国西雅图", code: "Washington US" }, { name: "德国", code: "DE" }, { name: "德国柏林", code: "Berlin DE" }, { name: "德国慕尼黑", code: "Bavaria DE" }, { name: "法国", code: "FR" }, { name: "法国巴黎", code: "Île-de-France FR" }, { name: "法国马赛", code: "Provence-Alpes-Côte d'Azur FR" }, { name: "越南", code: "VN" }, { name: "巴西", code: "BR" }, { name: "墨西哥", code: "MX" }, { name: "韩国", code: "Seoul KR" }, { name: "韩国首尔", code: "KR" }, { name: "意大利", code: "IT" }, { name: "西班牙", code: "ES" }, { name: "西班牙马德里", code: "Comunidad de Madrid ES" }, { name: "西班牙马德里巴塞罗那", code: "Cataluña ES" }, { name: "土耳其", code: "TR" }, { name: "埃及", code: "EG" }, { name: "印度尼西亚", code: "ID" }, // 以下邮编末知 { name: "英国", code: "UK" }, { name: "英国伦敦", code: "London UK" }, { name: "中国", code: "CN" }, { name: "中国台湾", code: "TW" }, { name: "中国香港", code: "HK" }, { name: "日本", code: "JP" }, { name: "日本东京", code: "Tokyo JP" }, { name: "日本大坂", code: "Osaka JP" }, { name: "印度", code: "IN" }, { name: "澳大利亚", code: "AU" }, { name: "加拿大", code: "CA" }, { name: "加拿大多伦多", code: "Ontario CA" }, { name: "俄罗斯", code: "RU" }, { name: "南非", code: "ZA" }, { name: "沙特阿拉伯", code: "SA" }, { name: "阿根廷", code: "AR" }, { name: "尼日利亚", code: "NG" } ]; // 初始化国家选择下拉框 function initCountrySelect() { const select = document.getElementById('country'); countries.forEach(country => { const option = document.createElement('option'); option.value = country.code; option.textContent = country.name; select.appendChild(option); }); // 添加返回主页按钮的点击事件 document.querySelector('a[href="/about"]').addEventListener('click', function(e) { e.preventDefault(); showAbout(); }); // 添加返回主页按钮的点击事件(在页脚也添加了一个) document.querySelector('a[href="/"]').addEventListener('click', function(e) { e.preventDefault(); showHome(); }); } // 复制到剪贴板 function copyToClipboard(text) { navigator.clipboard.writeText(text).then(() => { const copied = document.getElementById('copied'); copied.classList.remove('hidden'); copied.classList.add('translate-y-0'); copied.classList.remove('translate-y-[-100%]'); setTimeout(() => { copied.classList.add('translate-y-[-100%]'); copied.classList.remove('translate-y-0'); setTimeout(() => { copied.classList.add('hidden'); }, 300); }, 2000); }); } // 显示/隐藏加载动画 function toggleLoading(show) { const loading = document.getElementById('loading'); if (show) { loading.classList.remove('hidden'); } else { loading.classList.add('hidden'); } } // 更改国家 function changeCountry(country) { toggleLoading(true); generateNewAddress(country); } // 保存地址 function saveAddress() { const note = prompt('请输入备注(可以留空)') || ''; const savedAddresses = JSON.parse(localStorage.getItem('savedAddresses') || '[]'); const newEntry = { note: note, name: document.getElementById('name').textContent, gender: document.getElementById('gender').textContent, phone: document.getElementById('phone').textContent, address: document.getElementById('address').textContent }; savedAddresses.push(newEntry); localStorage.setItem('savedAddresses', JSON.stringify(savedAddresses)); renderSavedAddresses(); } // 渲染保存的地址 function renderSavedAddresses() { const savedAddresses = JSON.parse(localStorage.getItem('savedAddresses') || '[]'); const tbody = document.querySelector('#savedAddressesTable tbody'); tbody.innerHTML = ''; savedAddresses.forEach((entry, index) => { const row = tbody.insertRow(); row.className = 'border-t border-gray-200 hover:bg-gray-50 transition-colors'; const cells = ['name', 'gender', 'phone', 'address', 'note', '']; cells.forEach((cell, i) => { const td = row.insertCell(); td.className = 'p-4'; if (i === cells.length - 1) { const deleteBtn = document.createElement('button'); deleteBtn.textContent = '删除'; deleteBtn.className = 'bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg transition-all transform hover:scale-105 focus:ring-2 focus:ring-red-500 focus:ring-opacity-50'; deleteBtn.onclick = () => { if (confirm('确定要删除这条记录吗?')) { savedAddresses.splice(index, 1); localStorage.setItem('savedAddresses', JSON.stringify(savedAddresses)); renderSavedAddresses(); } }; td.appendChild(deleteBtn); } else { td.textContent = entry[cell]; } }); }); } // 生成新地址 async function generateNewAddress(country) { if (!country) { country = document.getElementById('country').value; } toggleLoading(true); try { const response = await fetch(\`\${window.location.href}api?country=\${country}\`); const data = await response.json(); if (data.error) { alert(data.error); return; } // 提取邮编逻辑 const addressText = data.address || ''; const postcodeMatch = addressText.match(/\\b\\d{5}(?:\\-\\d{4})?\\b/g); // 匹配国际通用的邮编格式 const postcode = postcodeMatch ? postcodeMatch[0] : '未知『地址中倒数第2项提取』'; document.getElementById('name').textContent = data.name; document.getElementById('gender').textContent = data.gender; document.getElementById('phone').textContent = data.phone; document.getElementById('address').textContent = addressText; // 显示完整地址 document.getElementById('postcode').textContent = postcode; // 显示邮编 // 更新地图 document.getElementById('map').src = \`https://www.google.com/maps?q=\${encodeURIComponent(data.address)}&output=embed\`; } catch (error) { console.error('Error fetching address:', error); showErrorModal('获取地址时发生错误,请检查网络后点击重试', () => { generateNewAddress(document.getElementById('country').value); }); } finally { toggleLoading(false); } } // 页面加载时初始化 window.onload = function() { initCountrySelect(); generateNewAddress(); renderSavedAddresses(); }; // 显示关于页面 function showAbout() { document.getElementById('main-content').classList.add('hidden'); document.getElementById('about').classList.remove('hidden'); } // 返回主页 function showHome() { document.getElementById('about').classList.add('hidden'); document.getElementById('main-content').classList.remove('hidden'); } </script> </body> </html>`; async function handleRequest(request) { const url = new URL(request.url); const path = url.pathname; // 处理 API 请求 if (path === '/api') { // 原有的 API 处理逻辑 return handleApiRequest(request); } // 处理根路径请求,返回 HTML 页面 return new Response(htmlContent, { headers: { 'Content-Type': 'text/html;charset=UTF-8', ...corsHeaders } }); } // 将原有的处理逻辑移到单独的函数中 async function handleApiRequest(request) { if (request.method === 'OPTIONS') { return new Response(null, { headers: corsHeaders }); } if (request.method !== 'GET') { return new Response('Method not allowed', { status: 405 }); } const url = new URL(request.url); const country = url.searchParams.get('country') || 'US'; if (!countryCoordinates[country]) { return new Response(JSON.stringify({ error: 'Invalid country code' }), { status: 400, headers: { 'Content-Type': 'application/json', ...corsHeaders } }); } let attempts = 0; const maxAttempts = 20; while (attempts < maxAttempts) { try { const location = getRandomLocation(country); const apiUrl = `https://nominatim.openstreetmap.org/reverse?format=json&lat=${location.lat}&lon=${location.lng}&zoom=18&addressdetails=1`; const response = await fetch(apiUrl, { headers: { 'User-Agent': 'Cloudflare Worker Random Address Generator' } }); const data = await response.json(); if (isValidAddress(data)) { let city = data.address.city || data.address.town || ''; city = city.split(';')[0].trim(); const address = `${data.address.house_number} ${data.address.road}, ${city}, ${data.address.postcode || ''}, ${country}`.replace(/\s+/g, ' ').trim(); const name = getRandomName(country); const gender = Math.random() > 0.4 ? 'Male男' : 'Female女'; const phone = getRandomPhoneNumber(country); const result = { name, gender, phone, address, coordinates: { lat: location.lat, lng: location.lng } }; return new Response(JSON.stringify(result), { headers: { 'Content-Type': 'application/json', ...corsHeaders } }); } attempts++; if (attempts < maxAttempts) { await new Promise(resolve => setTimeout(resolve, 100)); } } catch (error) { attempts++; if (attempts < maxAttempts) { await new Promise(resolve => setTimeout(resolve, 100)); } } } return new Response(JSON.stringify({ error: 'Failed to generate valid address after multiple attempts' }), { status: 500, headers: { 'Content-Type': 'application/json', ...corsHeaders } }); } // 注册事件监听器 addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)); }); 2025年07月15日更新,界面调整,添加多个国家和地区// 国家坐标数据 const countryCoordinates = { "US": [{ lat: 37.7749, lng: -122.4194 }, { lat: 34.0522, lng: -118.2437 }, { lat: 32.7767, lng: -96.7970 }, { lat: 41.8781, lng: -87.6298 }], "NY US": [{ lat: 40.7128, lng: -74.0060 }], "California US": [{ lat: 34.0522, lng: -118.2437 }], "Texas US": [{ lat: 32.7767, lng: -96.7970 }], "CA US": [{ lat: 37.3382, lng: -121.8863 }], "Illinois US": [{ lat: 41.8781, lng: -87.6298 }], "UK": [{ lat: 51.5074, lng: -0.1278 }, { lat: 53.4808, lng: -2.2426 }], "FR": [{ lat: 48.8566, lng: 2.3522 }, { lat: 45.7640, lng: 4.8357 }], "DE": [{ lat: 52.5200, lng: 13.4050 }, { lat: 48.1351, lng: 11.5820 }], "CN": [{ lat: 39.9042, lng: 116.4074 }, { lat: 31.2304, lng: 121.4737 }], "TW": [{ lat: 25.0330, lng: 121.5654 }, { lat: 22.6273, lng: 120.3014 }], "HK": [{ lat: 22.3193, lng: 114.1694 },{ lat: 22.3964, lng: 114.1095 }], "JP": [{ lat: 35.6895, lng: 139.6917 }, { lat: 34.6937, lng: 135.5023 }], "IN": [{ lat: 28.6139, lng: 77.2090 }, { lat: 19.0760, lng: 72.8777 }], "AU": [{ lat: -33.8688, lng: 151.2093 }, { lat: -37.8136, lng: 144.9631 }], "BR": [{ lat: -23.5505, lng: -46.6333 }, { lat: -22.9068, lng: -43.1729 }], "CA": [{ lat: 43.651070, lng: -79.347015 }, { lat: 45.501690, lng: -73.567253 }], "RU": [{ lat: 55.7558, lng: 37.6173 }, { lat: 59.9343, lng: 30.3351 }], "ZA": [{ lat: -33.9249, lng: 18.4241 }, { lat: -26.2041, lng: 28.0473 }], "MX": [{ lat: 19.4326, lng: -99.1332 }, { lat: 20.6597, lng: -103.3496 }], "KR": [{ lat: 37.5665, lng: 126.9780 }, { lat: 35.1796, lng: 129.0756 }], "IT": [{ lat: 41.9028, lng: 12.4964 }, { lat: 45.4642, lng: 9.1900 }], "ES": [{ lat: 40.4168, lng: -3.7038 }, { lat: 41.3851, lng: 2.1734 }], "TR": [{ lat: 41.0082, lng: 28.9784 }, { lat: 39.9334, lng: 32.8597 }], "SA": [{ lat: 24.7136, lng: 46.6753 }, { lat: 21.3891, lng: 39.8579 }], "AR": [{ lat: -34.6037, lng: -58.3816 }, { lat: -31.4201, lng: -64.1888 }], "EG": [{ lat: 30.0444, lng: 31.2357 }, { lat: 31.2156, lng: 29.9553 }], "NG": [{ lat: 6.5244, lng: 3.3792 }, { lat: 9.0579, lng: 7.4951 }], "ID": [{ lat: -6.2088, lng: 106.8456 }, { lat: -7.7956, lng: 110.3695 }], "VN": [{ lat: 21.0285, lng: 105.8048 }, { lat: 10.7626, lng: 106.6602 }], // 添加越南坐标数据 }; // 姓名数据 const namesByCountry = { "CN": { first: ["李", "王", "张", "刘", "陈", "杨", "黄", "赵", "吴", "周", "孙", "苏", "马", "朱", "候", "郭", "黑", "高", "林", "钱", "冯", "卫", "蒋", "许", "吕", "施", "曹", "严", "魏", "陶", "方", "雷"], last: ["力", "斌", "那", "真", "杰", "京", "丽", "晴", "来", "东", "勇", "仕", "云", "洁", "山", "伟", "明", "亮", "刚", "飞", "英", "兴", "浩", "曙光", "平", "志远", "志珍", "第一", "建国", "玉仙", "现红", "瑞山", "一山", "新丽", "思思", "青凤", "秀美"] }, "JP": { first: ["Sato", "Suzuki", "Takahashi", "Tanaka", "Watanabe", "Ito", "Yamamoto", "Nakamura", "Kobayashi", "Kato"], last: ["Shota", "Ren", "Hina", "Yui", "Hiroto", "Sota", "Yota", "Misaki", "Nanami", "Yuto"] }, "KR": { first: ["Kim", "Lee", "Park", "Choi", "Jung", "Kang", "Jo", "Yoon", "Jang", "Lim"], last: ["Minjun", "Seojun", "Doyun", "Jiho", "Jihun", "Seoyeon", "Seoyun", "Jiwoo", "Seohyun", "Minseo"] }, "TW": { first: ["Chen", "Lin", "Huang", "Chang", "Lee", "Wang", "Wu", "Liu", "Tsai", "Yang"], last: ["Zhiming", "Jianhong", "Junjie", "Yijun", "Shufen", "Meiling", "Yating", "Jiahao", "Zhihao", "Shuhui"] }, "HK": { first: ["Chan", "Lee", "Wong", "Cheung", "Lau", "Wang", "Ng", "Cheng", "Leung", "Ho"], last: ["Chiming", "Kayan", "Junjie", "Wingsze", "Kaming", "Meiling", "Kahao", "Winger", "Chihao", "Shukfan"] }, "US": { first: ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez"], last: ["James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph", "Thomas", "Christopher"] }, "NY US": { first: ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez"], last: ["James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph", "Thomas", "Christopher"] }, "California US": { first: ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez"], last: ["James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph", "Thomas", "Christopher"] }, "Texas US": { first: ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez"], last: ["James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph", "Thomas", "Christopher"] }, "CA US": { first: ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez"], last: ["James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph", "Thomas", "Christopher"] }, "Illinois US": { first: ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez"], last: ["James", "John", "Robert", "Michael", "William", "David", "Richard", "Joseph", "Thomas", "Christopher"] }, "UK": { first: ["Smith", "Jones", "Williams", "Taylor", "Brown", "Davies", "Evans", "Wilson", "Thomas", "Roberts"], last: ["Oliver", "Jack", "Harry", "George", "Noah", "Charlie", "Jacob", "Oscar", "William", "Leo"] }, "FR": { first: ["Martin", "Bernard", "Dubois", "Thomas", "Robert", "Richard", "Petit", "Durand", "Leroy", "Moreau"], last: ["Lucas", "Louis", "Gabriel", "Arthur", "Jules", "Hugo", "Leo", "Adam", "Raphael", "Paul"] }, "DE": { first: ["Mueller", "Schmidt", "Schneider", "Fischer", "Weber", "Meyer", "Wagner", "Becker", "Schulz", "Hoffmann"], last: ["Ben", "Paul", "Leon", "Noah", "Luis", "Finn", "Felix", "Jonas", "Maximilian", "Henry"] }, "IT": { first: ["Rossi", "Ferrari", "Russo", "Bianchi", "Romano", "Gallo", "Costa", "Fontana", "Conti", "Esposito"], last: ["Leonardo", "Francesco", "Alessandro", "Lorenzo", "Matteo", "Andrea", "Gabriele", "Marco", "Antonio", "Giuseppe"] }, "ES": { first: ["Garcia", "Rodriguez", "Gonzalez", "Fernandez", "Lopez", "Martinez", "Sanchez", "Perez", "Martin", "Gomez"], last: ["Antonio", "Jose", "Manuel", "Francisco", "David", "Juan", "Miguel", "Javier", "Rafael", "Carlos"] }, "BR": { first: ["Silva", "Santos", "Oliveira", "Souza", "Rodrigues", "Ferreira", "Alves", "Pereira", "Lima", "Gomes"], last: ["Miguel", "Arthur", "Heitor", "Pedro", "Davi", "Gabriel", "Bernardo", "Lucas", "Matheus", "Rafael"] }, "RU": { first: ["Ivanov", "Smirnov", "Kuznetsov", "Popov", "Vasiliev", "Petrov", "Sokolov", "Mikhailov", "Fedorov", "Morozov"], last: ["Alexander", "Dmitry", "Maxim", "Ivan", "Andrey", "Mikhail", "Artem", "Daniel", "Roman", "Sergey"] }, "IN": { first: ["Kumar", "Singh", "Sharma", "Patel", "Gupta", "Shah", "Verma", "Rao", "Reddy", "Joshi"], last: ["Aarav", "Vihaan", "Vivaan", "Aditya", "Arjun", "Reyansh", "Ayaan", "Sai", "Krishna", "Ishaan"] }, "AU": { first: ["Smith", "Jones", "Williams", "Brown", "Wilson", "Taylor", "Johnson", "White", "Anderson", "Thompson"], last: ["Oliver", "William", "Jack", "Noah", "Thomas", "James", "Lucas", "Henry", "Ethan", "Alexander"] }, "CA": { first: ["Smith", "Brown", "Tremblay", "Martin", "Roy", "Wilson", "MacDonald", "Taylor", "Campbell", "Anderson"], last: ["Liam", "Noah", "Oliver", "William", "James", "Benjamin", "Lucas", "Henry", "Theodore", "Jack"] }, "MX": { first: ["Garcia", "Rodriguez", "Martinez", "Lopez", "Gonzalez", "Perez", "Sanchez", "Ramirez", "Torres", "Flores"], last: ["Santiago", "Mateo", "Sebastian", "Leonardo", "Diego", "Daniel", "Gabriel", "Adrian", "David", "Alexander"] }, "TR": { first: ["Yilmaz", "Kaya", "Demir", "Sahin", "Celik", "Yildiz", "Erdogan", "Ozturk", "Aydin", "Ozdemir"], last: ["Yusuf", "Eymen", "Ömer", "Mustafa", "Ali", "Mehmet", "Ahmet", "Emir", "Hamza", "Ibrahim"] }, "SA": { first: ["Al-Saud", "Al-Sheikh", "Al-Rashid", "Al-Qahtani", "Al-Ghamdi", "Al-Zahrani", "Al-Dossari", "Al-Shammari", "Al-Otaibi", "Al-Harbi"], last: ["Mohammed", "Abdullah", "Ahmed", "Ali", "Omar", "Ibrahim", "Khalid", "Hassan", "Fahad", "Abdul"] }, "AR": { first: ["Gonzalez", "Rodriguez", "Garcia", "Fernandez", "Lopez", "Martinez", "Perez", "Romero", "Sanchez", "Diaz"], last: ["Mateo", "Thiago", "Benjamin", "Valentino", "Santiago", "Juan", "Lucas", "Martin", "Nicolas", "Joaquin"] }, "EG": { first: ["Mohamed", "Ahmed", "Mahmoud", "Ibrahim", "Ali", "Hassan", "Hussein", "Mostafa", "Kamal", "Samir"], last: ["Omar", "Youssef", "Adam", "Malik", "Zain", "Hamza", "Kareem", "Hassan", "Ali", "Ibrahim"] }, "NG": { first: ["Okafor", "Adebayo", "Okonkwo", "Eze", "Oluwaseun", "Adegoke", "Afolabi", "Ogunleye", "Adeniyi", "Adesina"], last: ["Oluwadamilare", "Oluwatobiloba", "Ayomide", "Temitope", "Oluwaseun", "Adebayo", "Chibuike", "Chisom", "Chidi", "Obinna"] }, "ID": { first: ["Wijaya", "Kusuma", "Suryanto", "Halim", "Santoso", "Tanaka", "Wibowo", "Susanto", "Hidayat", "Putra"], last: ["Muhammad", "Ahmad", "Abdul", "Aditya", "Budi", "Dimas", "Eko", "Fajar", "Gading", "Hadi"] }, "ZA": { first: ["Nkosi", "Van der Merwe", "Botha", "Mkhize", "Khumalo", "Pretorius", "Venter", "Ndlovu", "Fourie", "Nel"], last: ["Bandile", "Themba", "Sipho", "Thabo", "Jabu", "Mandla", "Blessing", "Gift", "Lucky", "Precious"] }, "VN": { first: ["Nguyen", "Tran", "Le", "Pham", "Hoang", "Vu", "Do", "Dao", "Bui", "Dang"], last: ["Van", "Minh", "Thanh", "Ngoc", "Huu", "Quoc", "Xuan", "Duc", "Tuan", "Khanh"] } }; // 电话号码格式配置 const phoneFormats = { "US": { format: "+1 (XXX) XXX-XXXX", areaCodeRanges: [[201, 989]] }, "NY US": { format: "+1 (XXX) XXX-XXXX", areaCodeRanges: [[201, 989]] }, "California US": { format: "+1 (XXX) XXX-XXXX", areaCodeRanges: [[201, 989]] }, "Texas US": { format: "+1 (XXX) XXX-XXXX", areaCodeRanges: [[201, 989]] }, "CA US": { format: "+1 (XXX) XXX-XXXX", areaCodeRanges: [[201, 989]] }, "Illinois US": { format: "+1 (XXX) XXX-XXXX", areaCodeRanges: [[201, 989]] }, "CN": { format: "+86 1XX-XXXX-XXXX", mobilePrefix: ["30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "50", "51", "52", "53", "55", "56", "57", "58", "59", "66", "70", "71", "72", "73", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89"] }, "JP": { format: "+81 XX-XXXX-XXXX", mobilePrefix: ["70", "80", "90"] }, "KR": { format: "+82 10-XXXX-XXXX" }, "UK": { format: "+44 7XXX XXXXXX", mobilePrefix: ["7"] }, "FR": { format: "+33 6 XX XX XX XX", mobilePrefix: ["6", "7"] }, "DE": { format: "+49 15X XXXXXXXX", mobilePrefix: ["15", "16", "17"] }, "TW": { format: "+886 9XX-XXX-XXX" }, "HK": { format: "+852 XXXX XXXX", mobilePrefix: ["5", "6", "9"] }, "AU": { format: "+61 4XX XXX XXX", mobilePrefix: ["4"] }, "CA": { format: "+1 (XXX) XXX-XXXX", areaCodeRanges: [[204, 989]] }, "MX": { format: "+52 1XX XXX XXXX" }, "TR": { format: "+90 5XX XXX XXXX", mobilePrefix: ["5"] }, "SA": { format: "+966 5XX XXX XXXX", mobilePrefix: ["5"] }, "AR": { format: "+54 9XX XXXX-XXXX" }, "EG": { format: "+20 1XX XXX XXXX", mobilePrefix: ["1"] }, "NG": { format: "+234 8XX XXX XXXX", mobilePrefix: ["7", "8", "9"] }, "ID": { format: "+62 8XX-XXXX-XXXX", mobilePrefix: ["8"] }, "ZA": { format: "+27 8X XXX XXXX", mobilePrefix: ["6", "7", "8"] }, "VN": { format: "+84 9X XXX XXXX", mobilePrefix: ["9", "8"] } }; // 工具函数 function getRandomLocation(country) { const coordsArray = countryCoordinates[country]; const randomCity = coordsArray[Math.floor(Math.random() * coordsArray.length)]; const lat = randomCity.lat + (Math.random() - 0.5) * 0.1; const lng = randomCity.lng + (Math.random() - 0.5) * 0.1; return { lat, lng }; } function getRandomName(country) { if (!namesByCountry[country]) { return null; } const names = namesByCountry[country]; const firstName = names.first[Math.floor(Math.random() * names.first.length)]; const lastName = names.last[Math.floor(Math.random() * names.last.length)]; return `${firstName} ${lastName}`; } function generateAreaCode(ranges) { const range = ranges[Math.floor(Math.random() * ranges.length)]; const [min, max] = range; return Math.floor(min + Math.random() * (max - min + 1)); } function getRandomPhoneNumber(country) { const format = phoneFormats[country] || phoneFormats["US"]; let phone = format.format; if (format.areaCodeRanges) { const areaCode = generateAreaCode(format.areaCodeRanges); phone = phone.replace("XXX", areaCode); phone = phone.replace(/X/g, () => Math.floor(Math.random() * 10)); } else if (format.mobilePrefix) { const prefix = format.mobilePrefix[Math.floor(Math.random() * format.mobilePrefix.length)]; // 先替换前缀 if (prefix.length === 2) { phone = phone.replace(/XX/, prefix); } else { phone = phone.replace(/X/, prefix); } // 然后替换剩余的X phone = phone.replace(/X/g, () => Math.floor(Math.random() * 10)); } else { phone = phone.replace(/X/g, () => Math.floor(Math.random() * 10)); } return phone; } function isValidAddress(data) { return data && data.address && data.address.house_number && data.address.road && (data.address.city || data.address.town); } // 处理CORS请求的headers const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, HEAD, POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type', }; // HTML 模板 const htmlContent = `<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>随机地址生成器</title> <script src="https://cdn.tailwindcss.com"></script> <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap" rel="stylesheet"> <script> tailwind.config = { theme: { extend: { animation: { 'gradient': 'gradient 8s linear infinite', }, keyframes: { gradient: { '0%, 100%': { 'background-size': '200% 200%', 'background-position': 'left center' }, '50%': { 'background-size': '200% 200%', 'background-position': 'right center' } } } } } } </script> </head> <link rel="shortcut icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2280%22>🌐</text></svg>"> <body class="bg-gradient-to-br from-blue-50 via-white to-blue-50 text-gray-800 min-h-screen font-['Noto_Sans_SC']"> <!-- 头部 --> <header class="bg-gradient-to-r from-blue-500 via-sky-500 to-blue-500 animate-gradient w-full p-6 shadow-lg"> <div class="max-w-4xl mx-auto flex items-center justify-between"> <div class="flex items-center gap-3"> <img src="https://img.freepik.com/premium-vector/minimal-location-map-icon-logo-symbol-vector-design-transparent_965979-613.jpg?w=2000" alt="Logo" class="w-12 h-12 transform hover:scale-105 transition-transform"> <h1 class="text-2xl font-bold text-white">随机地址生成器</h1> </div> <a href="https://www.199881.xyz" target="_blank" class="flex items-center gap-2 text-white hover:text-gray-200 transition-colors"> <svg viewBox="0 0 16 16" class="w-6 h-6 fill-current" aria-hidden="true"> <img src="https://cdn.glitch.global/efdace30-a873-49c7-aaa9-4fa31679ee0c/logo04.png?1741698119024" alt="GitHub" class="w-5 h-5 ml-1"> </svg> <span class="font-medium">导航</span> </a> </div> </header> <!-- 主要内容 --> <main class="container mx-auto px-4 py-8 max-w-5xl"> <!-- 加载动画 --> <div id="loading" class="hidden fixed inset-0 bg-white bg-opacity-75 backdrop-blur-sm flex items-center justify-center z-50"> <div class="bg-white rounded-2xl p-8 flex flex-col items-center shadow-2xl"> <div class="animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-blue-500 mb-4"></div> <div class="text-gray-800 text-lg font-medium">正在加载...</div> </div> </div> <div id="copied" class="hidden fixed top-4 right-4 bg-green-500 text-white px-6 py-3 rounded-lg shadow-lg z-40 transform transition-transform duration-300"> 已复制到剪贴板! </div> <!-- 国家选择 --> <div class="bg-white rounded-2xl shadow-xl p-6 border border-gray-200 mb-8"> <div class="flex flex-col sm:flex-row items-start sm:items-center gap-4"> <div class="w-full sm:w-auto flex flex-col sm:flex-row items-start sm:items-center gap-2 flex-grow"> <label for="country" class="text-blue-600 font-bold whitespace-nowrap">选择国家/地区:</label> <select id="country" onchange="changeCountry(this.value)" class="w-full bg-gray-50 border border-gray-200 rounded-xl p-3 text-gray-800 focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all"> </select> </div> <button onclick="generateNewAddress(document.getElementById('country').value)" class="w-full sm:w-auto bg-gradient-to-r from-blue-500 to-sky-500 hover:from-blue-600 hover:to-sky-600 text-white font-bold py-3 px-6 rounded-xl transition-all transform hover:scale-105 hover:shadow-lg focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50"> 获取新地址 </button> </div> </div> <div class="grid grid-cols-1 lg:grid-cols-2 gap-8"> <!-- 左侧面板 --> <div class="space-y-6"> <!-- 信息卡片 --> <div class="bg-white rounded-2xl shadow-xl p-6 border border-gray-200"> <h2 class="text-xl font-bold mb-6 text-blue-600">个人信息</h2> <div class="space-y-4"> <div class="bg-gray-50 p-4 rounded-xl cursor-pointer hover:bg-gray-100 transition-all transform hover:scale-[1.02] hover:shadow-lg" onclick="copyToClipboard(this.querySelector('span').textContent)"> <strong class="text-blue-600">姓名:</strong><span id="name" class="ml-2"></span> </div> <div class="bg-gray-50 p-4 rounded-xl cursor-pointer hover:bg-gray-100 transition-all transform hover:scale-[1.02] hover:shadow-lg" onclick="copyToClipboard(this.querySelector('span').textContent)"> <strong class="text-blue-600">性别:</strong><span id="gender" class="ml-2"></span> </div> <div class="bg-gray-50 p-4 rounded-xl cursor-pointer hover:bg-gray-100 transition-all transform hover:scale-[1.02] hover:shadow-lg" onclick="copyToClipboard(this.querySelector('span').textContent)"> <strong class="text-blue-600">电话:</strong><span id="phone" class="ml-2"></span> </div> <div class="bg-gray-50 p-4 rounded-xl cursor-pointer hover:bg-gray-100 transition-all transform hover:scale-[1.02] hover:shadow-lg" onclick="copyToClipboard(this.querySelector('span').textContent)"> <strong class="text-blue-600">地址:</strong><span id="address" class="ml-2"></span> </div> </div> </div> <!-- 保存按钮 --> <button onclick="saveAddress()" class="w-full bg-gradient-to-r from-green-500 to-emerald-500 hover:from-green-600 hover:to-emerald-600 text-white font-bold py-3 px-6 rounded-xl transition-all transform hover:scale-105 hover:shadow-lg focus:ring-2 focus:ring-green-500 focus:ring-opacity-50"> 保存地址 </button> </div> <!-- 右侧面板 --> <div class="space-y-6"> <!-- 地图 --> <div class="bg-white rounded-2xl shadow-xl p-6 border border-gray-200"> <h2 class="text-xl font-bold mb-6 text-blue-600">地图预览</h2> <iframe id="map" class="w-full h-[360px] rounded-xl border border-gray-200"></iframe> </div> </div> </div> <!-- 已保存的地址表格 --> <div class="mt-8 bg-white rounded-2xl shadow-xl p-6 border border-gray-200"> <h2 class="text-xl font-bold mb-6 text-blue-600">已保存的地址</h2> <div class="overflow-x-auto"> <table class="w-full border-collapse" id="savedAddressesTable"> <thead> <tr class="bg-gradient-to-r from-blue-500 to-sky-500 text-white"> <th class="p-4 text-left rounded-tl-lg">姓名</th> <th class="p-4 text-left">性别</th> <th class="p-4 text-left">电话</th> <th class="p-4 text-left">地址</th> <th class="p-4 text-left">备注</th> <th class="p-4 text-left rounded-tr-lg">操作</th> </tr> </thead> <tbody></tbody> </table> </div> </div> </main> <!-- 页脚 --> <footer class="text-center py-8 text-gray-600 text-sm mt-8 bg-gray-50 border-t border-gray-200"> <p class="max-w-4xl mx-auto px-4"> 总访问量 <span id="busuanzi_site_pv"></span> 次 | <span id="timeDate">载入天数...</span> | <a href="https://boke.199881.xyz/" target="_blank"> <span style="color: blue;">博客 | <a href="https://www.199881.xyz/" target="_blank"> <span style="color: green;">导航 <a href="https://github.com/jiangnan1224/AddressGenerator/" target="_blank" class="inline-flex items-center hover:text-blue-600 transition-colors"> <img src="https://pic.imgdb.cn/item/66e7ab36d9c307b7e9cefd24.png" alt="GitHub" class="w-5 h-5 ml-1"> </a> <script language="javascript"> var now = new Date(); function createtime(){ var grt= new Date("04/23/2025 00:00:00");/*---这里是网站的启用时间--*/ now.setTime(now.getTime()+250); days = (now - grt ) / 1000 / 60 / 60 / 24; dnum = Math.floor(days); document.getElementById("timeDate").innerHTML = "运行"+dnum+"天"; } setInterval("createtime()",250); </script> <script defer src="https://bsz.211119.xyz/js"></script> </p> </footer> <script> // 国家数据 const countries = [ { name: "美国", code: "US" }, { name: "美国纽约", code: "NY US" }, { name: "美国洛杉矶", code: "California US" }, { name: "美国达拉斯", code: "Texas US" }, { name: "美国圣何塞", code: "CA US" }, { name: "美国芝加哥", code: "Illinois US" }, { name: "英国", code: "UK" }, { name: "法国", code: "FR" }, { name: "德国", code: "DE" }, { name: "中国", code: "CN" }, { name: "中国台湾", code: "TW" }, { name: "中国香港", code: "HK" }, { name: "日本", code: "JP" }, { name: "越南", code: "VN" }, { name: "印度", code: "IN" }, { name: "澳大利亚", code: "AU" }, { name: "巴西", code: "BR" }, { name: "加拿大", code: "CA" }, { name: "俄罗斯", code: "RU" }, { name: "南非", code: "ZA" }, { name: "墨西哥", code: "MX" }, { name: "韩国", code: "KR" }, { name: "意大利", code: "IT" }, { name: "西班牙", code: "ES" }, { name: "土耳其", code: "TR" }, { name: "沙特阿拉伯", code: "SA" }, { name: "阿根廷", code: "AR" }, { name: "埃及", code: "EG" }, { name: "尼日利亚", code: "NG" }, { name: "印度尼西亚", code: "ID" } ]; // 初始化国家选择下拉框 function initCountrySelect() { const select = document.getElementById('country'); countries.forEach(country => { const option = document.createElement('option'); option.value = country.code; option.textContent = country.name; select.appendChild(option); }); } // 复制到剪贴板 function copyToClipboard(text) { navigator.clipboard.writeText(text).then(() => { const copied = document.getElementById('copied'); copied.classList.remove('hidden'); copied.classList.add('translate-y-0'); copied.classList.remove('translate-y-[-100%]'); setTimeout(() => { copied.classList.add('translate-y-[-100%]'); copied.classList.remove('translate-y-0'); setTimeout(() => { copied.classList.add('hidden'); }, 300); }, 2000); }); } // 显示/隐藏加载动画 function toggleLoading(show) { const loading = document.getElementById('loading'); if (show) { loading.classList.remove('hidden'); } else { loading.classList.add('hidden'); } } // 更改国家 function changeCountry(country) { toggleLoading(true); generateNewAddress(country); } // 保存地址 function saveAddress() { const note = prompt('请输入备注(可以留空)') || ''; const savedAddresses = JSON.parse(localStorage.getItem('savedAddresses') || '[]'); const newEntry = { note: note, name: document.getElementById('name').textContent, gender: document.getElementById('gender').textContent, phone: document.getElementById('phone').textContent, address: document.getElementById('address').textContent }; savedAddresses.push(newEntry); localStorage.setItem('savedAddresses', JSON.stringify(savedAddresses)); renderSavedAddresses(); } // 渲染保存的地址 function renderSavedAddresses() { const savedAddresses = JSON.parse(localStorage.getItem('savedAddresses') || '[]'); const tbody = document.querySelector('#savedAddressesTable tbody'); tbody.innerHTML = ''; savedAddresses.forEach((entry, index) => { const row = tbody.insertRow(); row.className = 'border-t border-gray-200 hover:bg-gray-50 transition-colors'; const cells = ['name', 'gender', 'phone', 'address', 'note', '']; cells.forEach((cell, i) => { const td = row.insertCell(); td.className = 'p-4'; if (i === cells.length - 1) { const deleteBtn = document.createElement('button'); deleteBtn.textContent = '删除'; deleteBtn.className = 'bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg transition-all transform hover:scale-105 focus:ring-2 focus:ring-red-500 focus:ring-opacity-50'; deleteBtn.onclick = () => { if (confirm('确定要删除这条记录吗?')) { savedAddresses.splice(index, 1); localStorage.setItem('savedAddresses', JSON.stringify(savedAddresses)); renderSavedAddresses(); } }; td.appendChild(deleteBtn); } else { td.textContent = entry[cell]; } }); }); } // 生成新地址 async function generateNewAddress(country) { if (!country) { country = document.getElementById('country').value; } toggleLoading(true); try { const response = await fetch(\`\${window.location.href}api?country=\${country}\`); const data = await response.json(); if (data.error) { alert(data.error); return; } document.getElementById('name').textContent = data.name; document.getElementById('gender').textContent = data.gender; document.getElementById('phone').textContent = data.phone; document.getElementById('address').textContent = data.address; // 更新地图 document.getElementById('map').src = \`https://www.google.com/maps?q=\${encodeURIComponent(data.address)}&output=embed\`; } catch (error) { console.error('Error fetching address:', error); alert('获取地址时发生错误,请重试'); } finally { toggleLoading(false); } } // 页面加载时初始化 window.onload = function() { initCountrySelect(); generateNewAddress(); renderSavedAddresses(); }; </script> </body> </html>`; async function handleRequest(request) { const url = new URL(request.url); const path = url.pathname; // 处理 API 请求 if (path === '/api') { // 原有的 API 处理逻辑 return handleApiRequest(request); } // 处理根路径请求,返回 HTML 页面 return new Response(htmlContent, { headers: { 'Content-Type': 'text/html;charset=UTF-8', ...corsHeaders } }); } // 将原有的处理逻辑移到单独的函数中 async function handleApiRequest(request) { if (request.method === 'OPTIONS') { return new Response(null, { headers: corsHeaders }); } if (request.method !== 'GET') { return new Response('Method not allowed', { status: 405 }); } const url = new URL(request.url); const country = url.searchParams.get('country') || 'US'; if (!countryCoordinates[country]) { return new Response(JSON.stringify({ error: 'Invalid country code' }), { status: 400, headers: { 'Content-Type': 'application/json', ...corsHeaders } }); } let attempts = 0; const maxAttempts = 20; while (attempts < maxAttempts) { try { const location = getRandomLocation(country); const apiUrl = `https://nominatim.openstreetmap.org/reverse?format=json&lat=${location.lat}&lon=${location.lng}&zoom=18&addressdetails=1`; const response = await fetch(apiUrl, { headers: { 'User-Agent': 'Cloudflare Worker Random Address Generator' } }); const data = await response.json(); if (isValidAddress(data)) { let city = data.address.city || data.address.town || ''; city = city.split(';')[0].trim(); const address = `${data.address.house_number} ${data.address.road}, ${city}, ${data.address.postcode || ''}, ${country}`.replace(/\s+/g, ' ').trim(); const name = getRandomName(country); const gender = Math.random() > 0.4 ? 'Male男' : 'Female女'; const phone = getRandomPhoneNumber(country); const result = { name, gender, phone, address, coordinates: { lat: location.lat, lng: location.lng } }; return new Response(JSON.stringify(result), { headers: { 'Content-Type': 'application/json', ...corsHeaders } }); } attempts++; if (attempts < maxAttempts) { await new Promise(resolve => setTimeout(resolve, 100)); } } catch (error) { attempts++; if (attempts < maxAttempts) { await new Promise(resolve => setTimeout(resolve, 100)); } } } return new Response(JSON.stringify({ error: 'Failed to generate valid address after multiple attempts' }), { status: 500, headers: { 'Content-Type': 'application/json', ...corsHeaders } }); } // 注册事件监听器 addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)); });
2025年07月16日
1 阅读
0 评论
0 点赞
2025-06-29
Linux 重新安装使用
Linux 重新安装使用github项目 一.安装前准备 如果你不是root用户,请尝试执行以下命令切换获取root用户权限:sudo -s切换到root用户的默认方向cd ~然后继续下载并执行这个脚本。依赖项和操作系统支持以下列表,以安装到脚本支持的操作系统:1.Debian系列(Debian / Ubuntu / Kali):apt update -yapt install wget -y2.Alpine Linux:apk updateapk add bash wgetsed -i 's/root:\/bin\/ash/root:\/bin\/bash/g' /etc/passwd3.其它依赖项和操作系统看:github项目 二.下载系统wget --no-check-certificate -qO InstallNET.sh 'https://raw.githubusercontent.com/leitbogioro/Tools/master/Linux_reinstall/InstallNET.sh' && chmod a+x InstallNET.sh中国大陆服务器:wget --no-check-certificate -qO InstallNET.sh 'https://gitee.com/mb9e8j2/Tools/raw/master/Linux_reinstall/InstallNET.sh' && chmod a+x InstallNET.sh三.开始安装相应 Linux 系统 【默认用户名,对于 Linux:root,对于 Windows:管理员,默认密码,对于Linux: LeitboGi0ro ,对于Windows: Teddysun.com,默认端口,Linux 系统:与之前通过终端连接的系统相同。Windows 系统:3389 】1.Debian系统bash InstallNET.sh -debian2.Ubuntu 22.04bash InstallNET.sh -ubuntu3.Alpine Linux Edgebash InstallNET.sh -alpine4.CentOS 9 streambash InstallNET.sh -centos5.Windows 11 Pro for Workstationsbash InstallNET.sh -windows四.常用系统一键脚本一键 debian 11或12【安装debian 12系统,修改为debian 12,设置亚洲上海时区,密码为admin888,名称是admin888,bbr,建议安装前修改密码】bash <(curl -sSL https://raw.githubusercontent.com/leitbogioro/Tools/master/Linux_reinstall/InstallNET.sh) -debian 11 -timezone "Asia/Shanghai" -pwd 'admin888' -hostname "admin888" -swap "1024" --bbr五.其它说明对于 Debian,官方推荐的镜像列表在这里:https://www.debian.org/mirror/list.html高级用法,例如 Debian 11(推荐用于中国大陆以外的服务器)以更换为美国镜像的一键安装代码为例bash <(curl -sSL https://raw.githubusercontent.com/leitbogioro/Tools/master/Linux_reinstall/InstallNET.sh) -debian 11 -mirror "https://mirrors.ocf.berkeley.edu/debian/" -timezone "Asia/Shanghai" -pwd 'admin888' -hostname "admin888" -swap "1024" --bbr下面是各国镜像地址日本:bash InstallNET.sh -debian 12 -mirror "http://ftp.riken.jp/Linux/debian/debian/"香港:bash InstallNET.sh -debian 12 -mirror "http://ftp.hk.debian.org/debian/"新加坡:bash InstallNET.sh -debian 12 -mirror "http://ftp.sg.debian.org/debian/"韩国:bash InstallNET.sh -debian 12 -mirror "http://ftp.kaist.ac.kr/debian/"台湾:bash InstallNET.sh -debian 12 -mirror "http://ftp.tw.debian.org/debian/"美国:bash InstallNET.sh -debian 12 -mirror "https://mirrors.ocf.berkeley.edu/debian/"加拿大:bash InstallNET.sh -debian 12 -mirror "http://ftp.ca.debian.org/debian/"英国:bash InstallNET.sh -debian 12 -mirror "http://ftp.uk.debian.org/debian/"德国:bash InstallNET.sh -debian 12 -mirror "http://ftp.de.debian.org/debian/"
2025年06月29日
1 阅读
0 评论
0 点赞
2025-06-23
体育NBA直播观看网站合集
体育NBA直播观看网站合集 NBA直播网站很多,这里列几个比较稳定,广告少的直播网站当然看足球比赛直播也可以用腾讯体育直播:https://sports.qq.com/kbsweb/ 腾讯拥有很多体育比赛国内直播版权,视频清晰流畅腾讯NBA直播:https://sports.qq.com/kbsweb/#nba腾讯体育APP: https://sports.qq.com/kbsweb/kbsdown/515直播:http://www.515.tv/ 多直播源选择球吧网:https://www.ballbar.cc 这个直播源挺多的,很多体育比赛都有JRS直播站:http://www.jrszb.com黑白直播:https://www.heibaizhibo.com | APP下载狐狸直播:http://hulizb.net/河豚直播:https://www.hetun555.com/可乐直播:https://www.kelezhibo.com/ 还是有外围广告,APP下载地址UU球直播:http://uuqiu.com/抓饭直播:http://www.zhuafan.tech/ | APP下载9球直播:http://www.9qzb.com/liveTV:http://livetv.sx 国外体育直播网站,好像是俄罗斯的,很多种体育比赛直播都有http://livetv.sx/allupcomingsports/3/ 篮球直播http://livetv.sx/allupcomingsports/1/ 足球直播企鹅直播:https://live.qq.com/ 腾讯旗下体育直播网站JRKAN直播:http://www.jrskan.com/Jrkan备用域名1: http://jrsyyds.com/ | Jrkan备用域名2: http://jryyds.com/最新网址发布:http://qiumi1314.com/直播吧: https://www.zhibo8.cc/ 老牌体育直播网来球网:https://www.nowqiu.com/收米直播:https://www.ttshoumi.com/ 看名字就知道一样主播打外围广告山猫直播:https://shanmao.tv/山猫直播:https://smzb365.com/球吧网:https://www.b8b8.tv/雨燕直播:https://yuyanzb.live/新足球直播吧:http://www.xinzuqiu.com/全球直播:http://qqzb88.com/备用地址:http://wb70.qqzb.vip/斗球体育:https://www.qiutx.com/34433体育:https://34433ty.com/ | APP下载球吧网:https://www.zhibo1.cc/看球直播:http://kqzb.com/备用地址:http://kqzb0.com/球头条:https://www.qttzb.com 复赛用这个看比赛比较多,清晰度不错,默认腾讯直播源,可选国外原声直播。飞速直播:http://www.jrsnba.com/貔貅直播:https://www.pixiuzhibo.com APP下载NBA英文观赛指南NBA中文数据库: http://www.stat-nba.com/
2025年06月23日
3 阅读
0 评论
0 点赞
2025-06-22
可信、可持续的 AList 开源替代方案:OpenList
可信、可持续的 AList 开源替代方案:OpenList 参考文章:https://oplist.org/zh/guide/install/docker.html一个更可信、可持续的 AList 开源替代方案,防范未来可能的闭源、黑箱或不可信变更。 github项目 OpenList特色:1、OpenList 从一开始就设计为易于安装,并且可以在所有平台上使用。2、OpenList 支持多个存储提供商,包括本地存储、阿里云盘、OneDrive、Google Drive 等,且易于拓展。3、OpenList 支持所有 WebDAV 存储,这是一种用于访问文件的标准。4、自由切换明暗模式5、支持视频、音频、文档、PDF、图片预览等,甚至支持 ipa 安装6、使用浏览器的 stream api 支持打包下载,无需使用服务器 / 使用Aria2进行批量下载支持文件夹7、任何人都可以安全地将加密数据存储在远程存储提供商上。数据存储在保险箱中,提供商只能看到保险箱,看不到您的数据。安装方法一1、一键脚本curl -fsSL "https://docs.openlist.team/v3.sh" -o v3.sh && bash v3.sh2、面板管理命令使用命令:openlist 或者 openlist-manager3、自定义路径默认安装在 /opt/openlist 中。 自定义安装路径,将安装路径作为第二个参数添加,必须是绝对路径(如果路径以 openlist 结尾,则直接安装到给定路径,否则会安装在给定路径 openlist 目录下),如 安装到 /root:# Install curl -fsSL "https://docs.openlist.team/v3.sh" -o v3.sh && bash v3.sh install /root # update curl -fsSL "https://docs.openlist.team/v3.sh" -o v3.sh && bash v3.sh update /root # Uninstall curl -fsSL "https://docs.openlist.team/v3.sh" -o v3.sh && bash v3.sh uninstall /root启动: systemctl start openlist关闭: systemctl stop openlist状态: systemctl status openlist重启: systemctl restart openlist获取密码, 需要进入脚本安装OpenList的目录文件夹 內执行如下命令3.25.0以上版本将密码改成加密方式存储的hash值,无法直接反算出密码,如果忘记了密码只能通过重新 随机生成 或者 手动设置# 随机生成一个密码 ./openlist admin random # 手动设置一个密码,`NEW_PASSWORD`是指你需要设置的密码 ./openlist admin set NEW_PASSWORD{dotted startColor="#ff6c6c" endColor="#1989fa"/}安装方法二:使用 Docker注意:OpenList 官方 Docker 镜像尚未发布。此处 Docker 镜像地址尚未更新。docker run -d --restart=unless-stopped -v /etc/openlist:/opt/openlist/data -p 5244:5244 -e PUID=0 -e PGID=0 -e UMASK=022 --name="openlist" openlistteam/openlist:betadocker composeversion: '3.3' services: openlist: image: 'openlistteam/openlist:beta' container_name: openlist volumes: - '/etc/openlist:/opt/openlist/data' ports: - '5244:5244' environment: - PUID=0 - PGID=0 - UMASK=022 restart: unless-stopped稳定版:openlistteam/openlist:latest 或指定本版,如 openlistteam/openlist:beta( Latest暂未上线 )最新镜像版本,请参阅 https://hub.docker.com/r/openlistteam/openlist/tags开发版:openlistteam/openlist:beta查看管理员信息:3.25.0以上版本将密码改成加密方式存储的hash值,无法直接反算出密码,如果忘记了密码只能通过重新 随机生成 或者 手动设置# 随机生成一个密码 docker exec -it openlist ./openlist admin random # 手动设置一个密码,`NEW_PASSWORD`是指你需要设置的密码 docker exec -it openlist ./openlist admin set NEW_PASSWORD更新docker-compose 更新docker-compose pull docker-compose up -d
2025年06月22日
6 阅读
0 评论
0 点赞
2025-06-20
正版Office全家桶永久免费使用!完全通过官方下载,放心使用!
正版Office全家桶永久免费使用!完全通过官方下载,放心使用!本文参考: 零度博客 安装视频 1.office 软件部署工具:https://www.microsoft.com/en-us/download/details.aspx?id=491172.office 版本自定义工具:https://config.office.com/deploymentsettings3.基于KMS的 GVLK:https://learn.microsoft.com/zh-cn/deployoffice/vlactivation/gvlks安装文件setup.exe和配置文件config.xml放入office文件夹【只有两个文件】,配置好的office文件夹要放在桌面,然后以 管理员身份 运行CMD 进入命令终端下载命令:setup /download config.xml安装命令【安装前要卸载office软件】:setup /configure config.xml最后启动命令【一条一条进行,不要三条一次进行】:cd C:\Program Files\Microsoft Office\Office16 cscript ospp.vbs /sethst:kms.03k.org cscript ospp.vbs /act注意:如果你安装的是32位版本,那么启动命令第一个要改成:cd C:\Program Files (x86)\Microsoft Office\Office16
2025年06月20日
3 阅读
0 评论
0 点赞
2025-06-20
Microsoft Office下载地址合集——微软官方原版离线安装下载
Microsoft Office下载地址合集——微软官方原版离线安装下载Microsoft Visio 2021 专业版(简体中文)https://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/VisioPro2021Retail.imgMicrosoft Visio 2021 专业版(繁体中文)https://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-tw/VisioPro2021Retail.imgMicrosoft Visio 2021 专业版(英文)https://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/us-en/VisioPro2021Retail.img一、Office2021下载1、 专业增强版(强烈推荐):http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/ProPlus2021Retail.img2、 专业版:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Professional2021Retail.img3、 家庭学生版:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/HomeStudent2021Retail.img4、 家庭企业版:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/HomeBusiness2021Retail.img5、 独立版(不推荐):Word: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Word2021Retail.imgExcel: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Excel2021Retail.imgPowerPoint: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/PowerPoint2021Retail.imgOutlook: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Outlook2021Retail.imgAccess: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Access2021Retail.imgPublisher: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Publisher2021Retail.imgProject标准版: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/ProjectStd2021Retail.imgProject专业版: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/ProjectPro2021Retail.imgVisio标准版: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/VisioStd2021Retail.imgVisio专业版: http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/VisioPro2021Retail.img二、Office2019下载1、中文说明:专业增强版/零售版/32位64位二合一镜像文件名称:ProPlus2019Retail.img文件大小:3.51GBSHA1:d850365b23e1e1294112a51105a2892b2bd88eb9SHA256:f5bea5517a3879792c39127db77aa7e766b4a9897bf52bed0c7e5dc70ccbc3f8下载地址:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/ProPlus2019Retail.img2、版本名称:Microsoft Office 2019 Professional Retail中文说明:专业版/零售版/32位64位二合一镜像文件名称:Professional2019Retail.img文件大小:3.51GBSHA-1:231a9d12f0bd8fb54c3f286d63eca7ec53e595a4SHA-256:07bb6d9a62feaa60ed2eb0c0aa45c566958f2f312e37a290ab9b4608abb6f175下载地址:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Professional2019Retail.img3、版本名称:Microsoft Office 2019 HomeBusiness Retail中文说明:小型企业版/零售版文件名称:HomeBusiness2019Retail.img下载地址:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/HomeBusiness2019Retail.img4、版本名称:Microsoft Office 2019 ProjectStd Retail中文说明:Project标准版/零售版文件名称:ProjectStd2019Retail.img下载地址:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/ProjectStd2019Retail.img5、版本名称:Microsoft Office 2019 ProjectPro Retail中文说明:Project专业版/零售版文件名称:ProjectPro2019Retail.img下载地址:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/ProjectPro2019Retail.img6、版本名称:Microsoft Office 2019 VisioStd Retail中文说明:Visio标准版/零售版文件名称:VisioStd2019Retail.img下载地址:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/VisioStd2019Retail.img7、版本名称:Microsoft Office 2019 VisioPro Retail中文说明:Visio专业版/零售版文件名称:VisioPro2019Retail.img下载地址:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/VisioPro2019Retail.img8、微软原版独立版组件版本名称:Microsoft Office 2019 Access Retail中文说明:Access 零售版文件名称:Access2019Retail.img下载地址:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Access2019Retail.img9、版本名称:Microsoft Office 2019 Excel Retail中文说明:Excel 零售版文件名称:Excel2019Retail.img下载地址:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Excel2019Retail.img10、版本名称:Microsoft Office 2019 PowerPoint Retail中文说明:PowerPoint零售版文件名称:PowerPoint2019Retail.img下载地址:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/PowerPoint2019Retail.img11、版本名称:Microsoft Office 2019 Outlook Retail中文说明:Outlook零售版文件名称:Outlook2019Retail.img下载地址:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Outlook2019Retail.img12、版本名称:Microsoft Office 2019 Publisher Retail中文说明:Publisher 零售版文件名称:Publisher2019Retail.img下载地址:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Publisher2019Retail.img13、版本名称:Microsoft Office 2019 Word Retail中文说明:Word 零售版文件名称:Word2019Retail.img下载地址:http://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6ddf67d60/media/zh-cn/Word2019Retail.img三、Office2016下载1、Office Professional Plus 2016 (x86 and x64) - DVD (English) 详细信息文件名:en_office_professional_plus_2016_x86_x64_dvd_6962141.isoSHA1:213A8A0F8849516704101CB6C49F6A027B0D6D5F文件大小:2.26GB发布时间:2015-09-22ed2k://|file|en_office_professional_plus_2016_x86_x64_dvd_6962141.iso|2421989376|1B32860B8D8BF3EF2B1C30F79A766879|/2、Office Professional Plus 2016 (x86 and x64) - DVD (Chinese-Simplified) 详细信息文件名:cn_office_professional_plus_2016_x86_x64_dvd_6969182.isoSHA1:277926A41B472EE38CA0B36ED8F2696356DCC98F文件大小:2.41GB发布时间:2015-09-22ed2k://|file|cn_office_professional_plus_2016_x86_x64_dvd_6969182.iso|2588266496|27EEA4FE4BB13CD0ECCDFC24167F9E01|/3、Office Home and Business 2016 for Mac (Go to Office.com/setup to activate) (Mac) - DVD (Multiple Languages) 详细信息文件名:mu_office_home_and_business_2016_for_mac_mac_dvd_7027756.isoSHA1:4B228801760C32BFF3AD6C037E10826BD5539383文件大小:1.13GB发布时间:2015-09-22ed2k://|file|mu_office_home_and_business_2016_for_mac_mac_dvd_7027756.iso|1214924800|D6FA02597D30709949C4FEA6AA0F9D6B|/4、Project Professional 2016 (x86 and x64) - DVD (English) 详细信息文件名:en_project_professional_2016_x86_x64_dvd_6962236.isoSHA1:608277E9CB873BC30B69FAEE3D9E69770CC53C15文件大小:2.26GB发布时间:2015-09-22ed2k://|file|en_project_professional_2016_x86_x64_dvd_6962236.iso|2421987328|44E574BDBD104294FC6CBFED9FD0F583|/5、Project Professional 2016 (x86 and x64) - DVD (Chinese-Simplified) 详细信息文件名:cn_project_professional_2016_x86_x64_dvd_6966612.isoSHA1:245787253622D4D790F62012B578398EA78D8EA2文件大小:2.41GB发布时间:2015-09-22ed2k://|file|cn_project_professional_2016_x86_x64_dvd_6966612.iso|2588266496|DEF65A0A9B12D8A8B734528800F625D5|/6、Visio Professional 2016 (x86 and x64) - DVD (English) 详细信息文件名:en_visio_professional_2016_x86_x64_dvd_6962139.isoSHA1:5861FAC06C303ADE374F13BF67FEA54BD1D792B4文件大小:2.26GB发布时间:2015-09-22ed2k://|file|en_visio_professional_2016_x86_x64_dvd_6962139.iso|2421987328|56459B178C346A9D48E3205673B667EB|/7、Visio Professional 2016 (x86 and x64) - DVD (Chinese-Simplified) 详细信息文件名cn_visio_professional_2016_x86_x64_dvd_6970929.isoSHA1:E16292B938A284E14A79E4998209F5A4143DBF8A文件大小:2.41GB发布时间:2015-09-22ed2k://|file|cn_visio_professional_2016_x86_x64_dvd_6970929.iso|2588262400|52A997F3AF4E40B896C8E4677CF10E90|/四、Office2013下载1、Office Professional Plus 2013 64位简体中文版文件名: cn_office_professional_plus_2013_x64_dvd_1134006.iso语言: Chinese – SimplifiedSHA1:adb8d9d3095638f25e9df2e708100d64804586a7下载地址:ed2k://|file|cn_office_professional_plus_2013_x64_dvd_1134006.iso|914106368|E5FBAE9EE9CB35D5E777EA78F7F50410|/2、Office Professional Plus 2013 32位简体中文版文件名: cn_office_professional_plus_2013_x86_dvd_1134005.iso语言: Chinese – SimplifiedSHA1:e1ced98dc92081527c444dfcac2b0ac8606ba80a下载地址:ed2k://|file|cn_office_professional_plus_2013_x86_dvd_1134005.iso|806250496|2BD6850AF868C040A16C74BD36A01858|/3、Office Professional Plus 2013 64位繁体中文版文件名: ct_office_professional_plus_2013_x64_dvd_1134004.iso语言: Chinese – TraditionalSHA1:f3cef9b4f9aaaf2004885a270a226301c381d926下载地址:ed2k://|file|ct_office_professional_plus_2013_x64_dvd_1134004.iso|830060544|D9E593F33DF3BB4DC303B4BCD87913D0|/4、Office Professional Plus 2013 32位繁体中文版文件名: ct_office_professional_plus_2013_x86_dvd_1134003.iso语言: Chinese – TraditionalSHA1:1caa0efd5e325600943deb33faf54c05aba653f2下载地址:ed2k://|file|ct_office_professional_plus_2013_x86_dvd_1134003.iso|722210816|91F6BCFAE7152BF2ACF5A572191D4C14|/5、Office Professional Plus 2013 64位英文正式版文件名: en_office_professional_plus_2013_x64_dvd_1123674.iso语言: EnglishSHA1:377f1f97dbe99104cf053df3632377f07c9310c7下载地址:ed2k://|file|en_office_professional_plus_2013_x64_dvd_1123674.iso|806676480|D85136BE7371B4EB5ACFAD14E372541A|/6、Office Professional Plus 2013 32位英文正式版文件名: en_office_professional_plus_2013_x86_dvd_1123673.iso语言: EnglishSHA1:36a70d4d1a2f42282f4d7175a37264a57da35a91下载地址:ed2k://|file|en_office_professional_plus_2013_x86_dvd_1123673.iso|699004928|BB00273C2DA5FF775165D748DBFDA37C|/cut-off五、office 永久密钥NJHVR-FK6XR-M97MB-P8CXD-FM4PJNXVJY-X9T8G-Y6RWG-8VQ7V-PWHPTW8W6K-3N7KK-PXB9H-8TD8W-BWTH9N9J9Q-Q7MMP-XDDM6-63KKP-76FPM9DP6T-9AGWG-KWV33-9MPC8-JDCVF7G2HE-JR8KL-ABB9D-Y7789-GLNFLU2PWU-H7D9H-69T3B-JEYC2-3R2NGR8R8P-MTT6F-KLRPM-J7CAB-PJM8CA4XV7-QP9JN-E7FCB-VQFRD-4NLKCU272H-HH2F6-WDG36-ULUPX-PCHTJ7LR67-WTXPA-KLUHV-GEK2E-QW4CKEUYTH-3KWKL-PJMX7-XBCPW-9U2DD7B4BN-DQCH8-WFVMD-B9F3T-V6DVC9B3BN-4XMXD-C7C6B-7XJ22-RVWDP5TWCRT-QVNVH-XTKPM-BV2XX-QV7HC8DJJQ-8NR7B-7QY7D-VCGPF-TVJ92N8VWK-GP87X-HX6VF-99WD8-K2FQPFMWMQ-H8N8X-98WYT-GQVM8-TQ8DPXNW69-86KD3-YJHB6-YYYT3-B9892WHKNR-W6RXW-XBYTQ-6G76H-BDW92V2V9V-DNKXM-TWFJ7-BMC4V-WK892R6WNH-6J9M7-KHC4K-Y3CVB-DPFQPQQKF2-V2NWT-VFH63-XJ6GC-GQ8DPQQKDR-PNXG2-X3YJC-RPRK2-FX83V
2025年06月20日
1 阅读
0 评论
0 点赞
2025-06-19
用 lnmp环境 + Caddy2 快速部署php动、静态网站
用 lnmp环境 + Caddy2 快速部署php动、静态网站 Caddy2 是一个现代、高性能、自动 HTTPS 的 Web 服务器,比 Nginx 更简单,特别适合快速部署 PHP 网站。{dotted startColor="#ff6c6c" endColor="#1989fa"/}一、lnmp环境搭建 1.安装要求: 参考: lnmp环境搭建 CentOS/RHEL/Fedora/Debian/Ubuntu/Raspbian/Deepin/Aliyun/Amazon/Mint Linux发行版需要5GB以上可用空间,MySQL 5.7,MariaDB 10至少9GB剩余空间,MySQL8.0最新版至少25GB以上,如空间不够且是x86或x86_64架构MySQL可以选择Generic Binaries安装。需要128MB以上内存(128MB小内存VPS,Xen需有SWAP,OpenVZ至少要有128MB以上的vSWAP或突发内存),注意小内存请勿使用64位系统!安装MySQL 5.6或5.7及MariaDB 10必须1G以上内存,更高版本至少要2G内存!。安装PHP 7及以上版本必须1G以上内存!。VPS或服务器必须设置好可用的yum或apt-get源并确保能正常工作,离线安装需要增加 CheckMirror=n 参数!不要在非常新的Linux发行版上安装旧的PHP/MySQL版本,同理不要在旧的Linux发行版上安装非常新的PHP/MySQL版本。Linux下区分大小写,输入命令时请注意!如有通过yum或apt-get安装的MySQL/MariaDB请自行备份数据等相关文件!CentOS 5、6、8,Debian 6、7、8或更低版本官网已经结束支持无法直接使用,需自行更换vault或archive源!CentOS 6、8请用lnmp 1.9+版本进行安装!Ubuntu 18+,Debian 9+,Mint 19+,Deepin 15.7+及所有新的Linux发行版只能使用1.7+进行安装!PHP 7.1.*以下版本不支持Ubuntu 19+、Debian 10+等等非常新的Linux发行版!阿里云Ubuntu 14.04和22.04系统模版有问题不要用!!!要用的话论坛找解决方法PHP 7.4升级或安装必须CentOS 7+,Debian 8+,Ubuntu 16.04+且必须使用1.7+!!!MySQL 8.0.23以下版本升级或安装必须CentOS 8+,Debian 9+,Ubuntu 16.04+且必须使用1.7+!!!MySQL 8.0.24以上版本升级或安装必须Debian 11+,Ubuntu 20.04+,Fedora 33+,CentOS 9等gcc 10+的版本且必须使用1.9+,不满足要求请选择(Generic Binaries)二进制方式!!!MariaDB 10.*以上版本升级或安装必须CentOS 8+,Debian 10+,Ubuntu 18.04+等cmake版本高于3的系统或自行升级cmake!!!不满足要求使用lnmp 2.0选择(Generic Binaries)二进制方式。2、更新系统sudo apt update && sudo apt upgrade -y3.安装LNMP稳定版如需要安装LNMPA或LAMP,将./install.sh 后面的参数lnmp替换为lnmpa或lamp即可。同时也支持单独安装Nginx或数据库,命令为 ./install.sh nginx 或 ./install.sh db。wget https://soft.lnmp.com/lnmp/lnmp2.2.tar.gz -O lnmp2.2.tar.gz && tar zxf lnmp2.2.tar.gz && cd lnmp2.2 && ./install.sh lnmp输入对应MySQL或MariaDB版本前面的序号,回车进入下一步.如果选择MySQL/MariaDB如果有对应架构的二进制包会提示:”Using Generic Binaries [y/n]:“ 这一步是提示是否使用二进制安装,输入 y 为使用二进制安装,输入 n 为使用源码编译安装。如果没有提示说明当前架构没有对应的二进制安装包。设置MySQL的root密码(为了安全不输入直接回车将会设置为lnmp.org#随机数字)如果输入有错误需要删除时,可以按住Ctrl再按Backspace键进行删除(个别情况下是只需按Backspace键)。询问是否需要启用MySQL InnoDB,InnoDB引擎默认为开启,一般建议开启,直接回车或输入 y ,如果确定确实不需要该引擎可以输入 n,(MySQL 5.7+版本无法关闭InnoDB),输入完成,回车进入下一步。注意:选择PHP 7+版本时需要自行确认PHP版本是否与自己的程序兼容。输入要选择的PHP版本的序号,回车进入下一步,选择是否安装内存优化: 一般选择不优化 安装完成如果显示Nginx: OK,MySQL: OK,PHP: OK卸载lnmp一键安装包 在lnmp安装包目录下执行:./uninstall.sh按提示选择当前环境类型,回车确认,会删除lnmp相关程序组件,网站文件会保留,数据库目录会另外备份到 /root 目录下,如有另外需要保存的文件请在卸载前备份。{dotted startColor="#ff6c6c" endColor="#1989fa"/}二、Caddy2的安装1、必要的软件包1sudo apt install -y debian-keyring debian-archive-keyring curl2、必要的软件包2sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https3、Caddy的安全密钥curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg4、下载 Caddy密钥文件curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list5、更新软件包列表sudo apt update6、升级或安装Caddy2sudo apt install -y caddy{dotted startColor="#ff6c6c" endColor="#1989fa"/}三、创建网站目录,并上传静态html或动态php文件【网站文件在 home/html/web/】网站1sudo mkdir -p /home/html/web/web1 sudo chown -R www-data:www-data /home/html/web/web1 sudo chmod -R 755 /home/html/web/web1网站2sudo mkdir -p /home/html/web/web2 sudo chown -R www-data:www-data /home/html/web/web2 sudo chmod -R 755 /home/html/web/web2网站3sudo mkdir -p /home/html/web/web3 sudo chown -R www-data:www-data /home/html/web/web3 sudo chmod -R 755 /home/html/web/web3网站4sudo mkdir -p /home/html/web/web4 sudo chown -R www-data:www-data /home/html/web/web4 sudo chmod -R 755 /home/html/web/web4网站5sudo mkdir -p /home/html/web/web5 sudo chown -R www-data:www-data /home/html/web/web5 sudo chmod -R 755 /home/html/web/web5网站6sudo mkdir -p /home/html/web/web6 sudo chown -R www-data:www-data /home/html/web/web6 sudo chmod -R 755 /home/html/web/web6可以类似的创建更多网站四、配置 Caddy2 支持 PHP【以下面网站示例,多个网站类似配置,可以不开cf小黃云】example1.com { root * /home/html/web/web1 #安装路径,备注什么网站 php_fastcgi unix//run/php/php-fpm.sock file_server } example2.com { root * /home/html/web/web2 #安装路径,备注什么网站 php_fastcgi unix//run/php/php-fpm.sock file_server } example3.com { reverse_proxy 127.0.0.1:8880 #反代配置,这里输入你想反代的服务器IP和端口 encode gzip } example4.com { redir https://naiyous.com{uri} #重定向配置,这里输入你想设置的重定向 }五、启动并启用 Caddy2.重启Caddy2并设置开机自启sudo systemctl restart caddy sudo systemctl enable caddy其它命令1、Caddy2开机自启systemctl enable caddy2、重启Caddy2systemctl restart caddy3、停止Caddy2systemctl stop caddy
2025年06月19日
2 阅读
0 评论
0 点赞
2025-06-05
★★★在 Debian 11/12 上安装 PHP 8.2 + Caddy【MySQL 8.0或MariaDB数据库】
★★★在 Debian 11/12 上安装 PHP 8.2 + Caddy【MySQL 8.0或MariaDB数据库】 现在已集成到一键工具箱中了,进入后选11,支持 Debian11、12 和 UBT 等系统wget https://raw.githubusercontent.com/wszx123/gongjuxiang/refs/heads/main/toolbox.sh -O toolbox.sh && chmod +x toolbox.sh && ./toolbox.sh特别备注:1、Debian 12 (PHP 8.2) 上,如需要修改 php.ini 配置文件【不修改也可以,修改后可上传更大的文件等】,并重启 PHP 服务找到: /etc/php/8.2/fpm/php.in 修改为 upload_max_filesize = 20M 或更大 100M post_max_size = 80M 或更大 200M 可选:修改执行时间和内存限制(上传大文件推荐加上) max_execution_time = 300 max_input_time = 600 memory_limit = 256M 或更大2、安装 MySQL 8.0 和扩展(推荐)后默认配置是:用 户 名: wszx123_user 密 码: password@123@DDD 数据库名: wszx123_db Caddy 是一个现代、高性能、自动 HTTPS 的 Web 服务器,比 Nginx 更简单,特别适合快速部署 PHP 网站。这是一个一步到位的自动化建站脚本,包括:安装 Caddy(来自官方仓库)安装 PHP-FPM 及扩展创建网站目录配置 Caddy 支持 PHP可自动启用 HTTPS(如果绑定域名)一、在 Debian 11 上用 Caddy + PHP 快速部署动态 PHP 或静态html网站【6个步骤】1、更新系统sudo apt update && sudo apt upgrade -y2、安装 PHP 和常用扩展sudo apt install -y php php-fpm php-mysql php-cli php-curl php-gd php-mbstring php-xml php-zip unzip3、安装 Caddya、必要的软件包1sudo apt install -y debian-keyring debian-archive-keyring curl必要的软件包2sudo apt install -y debian-keyring debian-archive-keyring apt-transport-httpsb、Caddy的安全密钥curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpgc、下载 Caddy密钥文件curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.listd、更新软件包列表sudo apt updatee、升级或安装Caddy2sudo apt install -y caddy4、创建网站目录,并上传静态html或动态php文件【网站文件在 home/html/web/】网站1sudo mkdir -p /home/html/web/web1 sudo chown -R www-data:www-data /home/html/web/web1 sudo chmod -R 755 /home/html/web/web1 网站2sudo mkdir -p /home/html/web/web2 sudo chown -R www-data:www-data /home/html/web/web2 sudo chmod -R 755 /home/html/web/web2 网站3sudo mkdir -p /home/html/web/web3 sudo chown -R www-data:www-data /home/html/web/web3 sudo chmod -R 755 /home/html/web/web3 网站4sudo mkdir -p /home/html/web/web4 sudo chown -R www-data:www-data /home/html/web/web4 sudo chmod -R 755 /home/html/web/web4 网站5sudo mkdir -p /home/html/web/web5 sudo chown -R www-data:www-data /home/html/web/web5 sudo chmod -R 755 /home/html/web/web5 网站6sudo mkdir -p /home/html/web/web6 sudo chown -R www-data:www-data /home/html/web/web6 sudo chmod -R 755 /home/html/web/web6 可以类似的创建更多网站5、配置 Caddy 支持 PHP【以两个网站为例,多个网站类似配置,安装时不开cf小黃云。安装完后,不使用代理时不打开小黄云,使用 CF 代理 时打开小黄云, SSL/TLS证书必须设置为完全或完全(严格) ,否则网站打不开】example1.com { root * /home/html/web/web1 #安装路径,备注什么网站 php_fastcgi unix//run/php/php-fpm.sock file_server } example2.com { root * /home/html/web/web2 #安装路径,备注什么网站 php_fastcgi unix//run/php/php-fpm.sock file_server } http://[v6 ip]:端口 { root * /home/html/web/web3 #使用v6的 IP+端口 访问,v6 的 ip 必须放在[]中 php_fastcgi unix//run/php/php-fpm.sock file_server } example3.com { reverse_proxy 127.0.0.1:8880 #反代,这里输入你想反代的服务器IP和端口 encode gzip } example4.com { redir https://naiyous.com{uri} #重定向,这里输入你想设置的重定向 } 6、启动并启用 php*-fpm和Caddy,并设置开机自启【后面7、8、9一般不用】,大功告成。sudo systemctl enable php*-fpm sudo systemctl restart php*-fpm sudo systemctl enable caddy sudo systemctl restart caddy7、开启防火墙 ipv4或IPv6 端口(如果启用 UFW,例如要开启8080端口)sudo ufw allow 8080/tcp sudo ufw reload8、开机自启systemctl enable caddy重启Caddy2systemctl restart caddy9、停止Caddy2systemctl stop caddy二、【不用数据库可不安装,比如 WordPress、Typecho要用到】Debian 11 默认的软件源中没有 mysql-server 包,或者没有启用适当的源。Debian 通常推荐使用 MariaDB 替代 MySQLA、使用 MariaDB(兼容 MySQL) 1、 升级等sudo apt update sudo apt install -y mariadb-server sudo systemctl enable mariadb sudo systemctl start mariadb设置 root 密码【一定要修改默认的rootpass123为强密码,至少18位英文、数字加字符】sudo mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'rootpass123'; FLUSH PRIVILEGES;"2、登录 MariaDB:sudo mysql -u root -p # 然后输入密码:rootpass1233、创建数据库:CREATE DATABASE mydb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;你也可以:CREATE DATABASE mysite;4、给 root 用户授权(MariaDB 默认 root 用户已拥有所有权限)CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'localhost'; FLUSH PRIVILEGES;5、示例配置(适用于 WordPress/phpMyAdmin 等)配置项 值数据库名 mydb数据库用户名 root(或 myuser)数据库密码 rootpass123(或 mypassword)数据库主机 localhost6、如何在安装程序中填写(例如 WordPress/phpMyAdmin),安装时根据提示进行数据库主机:localhost表前缀:wp_ (或保留默认)数据库用户名: root 数据库名: mydb 数据库密码: rootpass123 B、Oracle 官方源安装了 MySQL Server 8.0 ,和上面的MariaDB(兼容 MySQL)一样1、升级等sudo apt update sudo apt install -y wget lsb-release gnupg2、下载官方源配置包# 下载官方源配置包 wget https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb3、安装该配置包【安装过程中要设置的 root 密码,记好,后面用到】# 安装该配置包 sudo dpkg -i mysql-apt-config_0.8.29-1_all.deb4、在弹出的菜单中,默认选中 MySQL 8.0,按回车确认5、再更新软件源# 再更新软件源 sudo apt update6、安装 MySQL Server# 安装 MySQL Server sudo apt install -y mysql-server7、登录 MySQL,然后输入你在安装时设置的 root 密码。sudo mysql -u root -p8、创建数据库,mydb 是你的网站或程序要使用的数据库名,可以根据需要修改。CREATE DATABASE mydb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;9、创建独立的数据库用户并授权CREATE USER 'myuser'@'localhost' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'localhost'; FLUSH PRIVILEGES;myuser 是你新建的数据库用户名mypassword 是你设置的密码localhost 表示只允许本地连接数据库10、(可选):查看创建情况SHOW DATABASES; SELECT user, host FROM mysql.user; SHOW GRANTS FOR 'myuser'@'localhost';数据库名 mydb数据库用户名 myuser密码 mypassword主机 localhost11、退出命令,随便一个都行exit; #退出quit; #退出一键部署脚本(保存为 setup_caddy_php.sh)#!/bin/bash set -e green() { echo -e "\033[32m$1\033[0m"; } green "▶ 更新系统..." sudo apt update && sudo apt upgrade -y green "▶ 安装 PHP 和常用扩展..." sudo apt install -y php php-fpm php-mysql php-cli php-curl php-gd php-mbstring php-xml php-zip unzip green "▶ 安装 Caddy..." sudo apt install -y debian-keyring debian-archive-keyring curl curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list sudo apt update sudo apt install -y caddy green "▶ 创建网站目录..." sudo mkdir -p /var/www/html/mysite sudo chown -R www-data:www-data /var/www/html/mysite green "▶ 写入 PHP 测试页..." cat <<EOF | sudo tee /var/www/html/mysite/index.php <?php phpinfo(); ?> EOF green "▶ 配置 Caddy 支持 PHP..." cat <<EOF | sudo tee /etc/caddy/Caddyfile :80 { root * /var/www/html/mysite php_fastcgi unix//run/php/php-fpm.sock file_server } EOF green "▶ 启动并启用 Caddy..." sudo systemctl enable php*-fpm sudo systemctl restart php*-fpm sudo systemctl restart caddy green "✅ 成功部署!请访问 http://你的-VPS-IP 查看 PHP 测试页。"二、使用方法步骤 1:上传并运行脚本nano setup_caddy_php.sh # 粘贴脚本内容 chmod +x setup_caddy_php.sh ./setup_caddy_php.sh或一键命令bash <(curl -fsSL https://raw.githubusercontent.com/wszx123/gongjuxiang/refs/heads/main/setup_caddy_php.sh)或bash <(wget -qO- https://raw.githubusercontent.com/wszx123/gongjuxiang/refs/heads/main/setup_caddy_php.sh)三、使用域名 + 自动 HTTPS(可选)如果你有域名(如 example.com)指向 VPS:编辑 /etc/caddy/Caddyfile 为:example.com { root * /var/www/html/mysite php_fastcgi unix//run/php/php-fpm.sock file_server }重启caddysudo systemctl reload caddyCaddy 会自动申请并配置 Let's Encrypt 证书(HTTPS)。四、总结组件说明Caddy替代 Nginx,自动 HTTPS,配置更简单PHP-FPM处理 PHP 动态请求运行目录/var/www/html/mysite/配置文件/etc/caddy/Caddyfile
2025年06月05日
1 阅读
11 评论
0 点赞
1
2
3
4
...
12
您是第
263709
位访客