// 国家坐标数据 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 }, {"lat": 23.1291, "lng": 113.2644}, {"lat": 30.6799, "lng": 104.0679}, {"lat": 30.2582, "lng": 120.1646}], "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 = ` 随机地址生成器
Logo

随机地址生成器

GitHub

个人信息

姓名:
性别:
电话:
地址:

地图预览

已保存的地址

姓名 性别 电话号码 地址 备注 操作
`; 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)); });