This commit is contained in:
严浩
2025-07-15 23:50:50 +08:00
parent 2d3c805fb9
commit edd66080af
2 changed files with 80 additions and 286 deletions

View File

@@ -9,7 +9,7 @@
// event.respondWith(handleRequest(event.request));
// });
export default {
async fetch(request, env, ctx) {
async fetch(request, _env, _ctx) {
return handleRequest(request);
},
};
@@ -17,7 +17,7 @@ export default {
async function handleRequest(request) {
const { searchParams } = new URL(request.url);
const state = searchParams.get('state') || getRandomState();
let address, name, gender, phone, country;
let address, phone, country;
const remoteProvinces = ['NL', 'NT', 'NU', 'YT']; // Remote Canadian Provinces/Territories
@@ -57,146 +57,47 @@ async function handleRequest(request) {
}
if (!address) {
return new Response('Failed to retrieve detailed address', { status: 500 });
return new Response(
JSON.stringify({ error: 'Failed to retrieve detailed address' }),
{
status: 500,
headers: { 'content-type': 'application/json;charset=UTF-8' }
}
);
}
const userResp = await fetch('https://fakerapi.it/api/v1/persons?_quantity=1&_locale=en_US');
const userJson = await userResp.json();
let firstName, lastName;
if (userJson && userJson.data && userJson.data.length > 0) {
const user = userJson.data[0];
name = `${user.firstname} ${user.lastname}`;
gender = user.gender.charAt(0).toUpperCase() + user.gender.slice(1);
firstName = user.firstname;
lastName = user.lastname;
phone = getRandomPhoneNumber(country, state);
} else {
name = getRandomName();
gender = 'Unknown';
const randomName = getRandomName();
const nameParts = randomName.split(' ');
firstName = nameParts[0];
lastName = nameParts[1];
phone = getRandomPhoneNumber(country, state);
}
const html = `
<!DOCTYPE html>
<html>
<head>
<title>Real US & Canadian Address Generator</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
min-height: 100vh;
background-color: #f0f0f0;
margin: 0;
}
.container {
text-align: center;
background: white;
padding: 20px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
width: 90%;
max-width: 600px;
margin: 20px;
box-sizing: border-box;
position: relative;
}
.name, .gender, .phone, .address {
font-size: 1.5em;
margin-bottom: 10px;
cursor: pointer;
}
.refresh-btn {
padding: 10px 20px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
margin-bottom: 20px;
}
.refresh-btn:hover {
background-color: #0056b3;
}
.state-select {
margin-bottom: 20px;
}
.map {
width: 100%;
height: 400px;
border: 0;
}
.title {
font-size: 2em;
margin: 20px 0;
}
.footer {
margin-top: auto;
padding: 10px 0;
background-color: #f0f0f0;
width: 100%;
text-align: center;
font-size: 0.9em;
}
.footer a {
color: #007bff;
text-decoration: none;
}
.footer a:hover {
text-decoration: underline;
}
.copied {
position: absolute;
top: 10px;
right: 10px;
background: #28a745;
color: white;
padding: 5px 10px;
border-radius: 5px;
display: none;
}
</style>
</head>
<body>
<div class="title">Real US & Canadian Address Generator</div>
<div class="container">
<div class="copied" id="copied">Copied!</div>
<div class="name" onclick="copyToClipboard('${name}')">${name}</div>
<div class="gender" onclick="copyToClipboard('${gender}')">${gender}</div>
<div class="phone" onclick="copyToClipboard('${phone.replace(/[()\s-]/g, '')}')">${phone}</div>
<div class="address" onclick="copyToClipboard('${address}')">${address}</div>
<button class="refresh-btn" onclick="window.location.reload();">Get Another Address</button>
<div class="state-select">
<label for="state">Select State/Province:</label>
<select id="state" onchange="changeState(this.value)">
${getStateOptions(state)}
</select>
</div>
<iframe class="map" src="https://www.google.com/maps?q=${encodeURIComponent(address)}&output=embed"></iframe>
</div>
<div class="footer">
© chatgpt.org.uk 2025 All rights reserved | <a href="https://chatgpt.org.uk" target="_blank">https://chatgpt.org.uk</a>
</div>
<script>
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
const copied = document.getElementById('copied')
copied.style.display = 'block'
setTimeout(() => {
copied.style.display = 'none'
}, 2000)
})
}
function changeState(state) {
window.location.href = \`?state=\${state}\`
}
</script>
</body>
</html>
`;
// Parse address components
const addressParts = parseAddressComponents(address, state);
return new Response(html, {
headers: { 'content-type': 'text/html;charset=UTF-8' },
const jsonResponse = {
firstName: firstName,
lastName: lastName,
streetAddress: addressParts.streetAddress,
aptSuiteBldg: addressParts.aptSuiteBldg,
city: addressParts.city,
state: addressParts.state,
zipCode: addressParts.zipCode,
phoneNumber: phone
};
return new Response(JSON.stringify(jsonResponse), {
headers: { 'content-type': 'application/json;charset=UTF-8' },
});
}
@@ -559,34 +460,7 @@ function getRandomPhoneNumber(country, state) {
AK: ['907'],
AZ: ['480', '520', '602', '623', '928'],
AR: ['479', '501', '870'],
CA: [
'209',
'213',
'310',
'323',
'408',
'415',
'424',
'510',
'530',
'559',
'562',
'619',
'626',
'650',
'661',
'707',
'714',
'760',
'805',
'818',
'831',
'858',
'909',
'916',
'925',
'949',
],
CA: [ '209', '213', '310', '323', '408', '415', '424', '510', '530', '559', '562', '619', '626', '650', '661', '707', '714', '760', '805', '818', '831', '858', '909', '916', '925', '949', ],
CO: ['303', '719', '720', '970'],
CT: ['203', '475', '860', '959'],
DE: ['302'],
@@ -613,27 +487,7 @@ function getRandomPhoneNumber(country, state) {
NH: ['603'],
NJ: ['201', '551', '609', '732', '848', '856', '862', '908', '973'],
NM: ['505', '575'],
NY: [
'212',
'315',
'332',
'347',
'516',
'518',
'585',
'607',
'631',
'646',
'680',
'716',
'718',
'838',
'845',
'914',
'917',
'929',
'934',
],
NY: [ '212', '315', '332', '347', '516', '518', '585', '607', '631', '646', '680', '716', '718', '838', '845', '914', '917', '929', '934', ],
NC: ['252', '336', '704', '743', '828', '910', '919', '980', '984'],
ND: ['701'],
OH: ['216', '234', '283', '330', '380', '419', '440', '513', '567', '614', '740', '937'],
@@ -644,33 +498,7 @@ function getRandomPhoneNumber(country, state) {
SC: ['803', '839', '843', '854', '864'],
SD: ['605'],
TN: ['423', '615', '629', '731', '865', '901', '931'],
TX: [
'210',
'214',
'254',
'281',
'325',
'346',
'409',
'430',
'432',
'469',
'512',
'682',
'713',
'737',
'806',
'817',
'830',
'832',
'903',
'915',
'936',
'940',
'956',
'972',
'979',
],
TX: [ '210', '214', '254', '281', '325', '346', '409', '430', '432', '469', '512', '682', '713', '737', '806', '817', '830', '832', '903', '915', '936', '940', '956', '972', '979', ],
UT: ['385', '435', '801'],
VT: ['802'],
VA: ['276', '434', '540', '571', '703', '757', '804'],
@@ -712,6 +540,50 @@ function getRandomPhoneNumber(country, state) {
return `(${areaCode}) ${exchangeCode}-${lineNumber}`;
}
function parseAddressComponents(fullAddress, state) {
// Parse the formatted address to extract components
const parts = fullAddress.split(', ');
let streetAddress = '';
let aptSuiteBldg = '';
let city = '';
let stateCode = '';
let zipCode = '';
if (parts.length >= 3) {
streetAddress = parts[0] || '';
city = parts[1] || '';
// Handle state and zip from the third part
if (parts[2]) {
const stateZipMatch = parts[2].match(/^([A-Z]{2})\s*([A-Z0-9\s-]*)/);
if (stateZipMatch) {
stateCode = stateZipMatch[1];
zipCode = stateZipMatch[2] ? stateZipMatch[2].trim() : '';
} else {
stateCode = state;
}
}
} else {
// For partial addresses
if (parts.length === 2) {
city = parts[0] || '';
const stateZipMatch = parts[1].match(/^([A-Z]{2})\s*([A-Z0-9\s-]*)/);
if (stateZipMatch) {
stateCode = stateZipMatch[1];
zipCode = stateZipMatch[2] ? stateZipMatch[2].trim() : '';
}
}
}
return {
streetAddress: streetAddress,
aptSuiteBldg: aptSuiteBldg, // Empty for now, could be enhanced
city: city,
state: stateCode || state,
zipCode: zipCode
};
}
function getRandomState() {
const states = [
// US States
@@ -728,84 +600,6 @@ function getRandomState() {
return states[Math.floor(Math.random() * states.length)];
}
function getStateOptions(selectedState) {
const states = [
// US States
{ full: 'Alabama', abbr: 'AL', country: 'US' },
{ full: 'Alaska', abbr: 'AK', country: 'US' },
{ full: 'Arizona', abbr: 'AZ', country: 'US' },
{ full: 'Arkansas', abbr: 'AR', country: 'US' },
{ full: 'California', abbr: 'CA', country: 'US' },
{ full: 'Colorado', abbr: 'CO', country: 'US' },
{ full: 'Connecticut', abbr: 'CT', country: 'US' },
{ full: 'Delaware', abbr: 'DE', country: 'US' },
{ full: 'Florida', abbr: 'FL', country: 'US' },
{ full: 'Georgia', abbr: 'GA', country: 'US' },
{ full: 'Hawaii', abbr: 'HI', country: 'US' },
{ full: 'Idaho', abbr: 'ID', country: 'US' },
{ full: 'Illinois', abbr: 'IL', country: 'US' },
{ full: 'Indiana', abbr: 'IN', country: 'US' },
{ full: 'Iowa', abbr: 'IA', country: 'US' },
{ full: 'Kansas', abbr: 'KS', country: 'US' },
{ full: 'Kentucky', abbr: 'KY', country: 'US' },
{ full: 'Louisiana', abbr: 'LA', country: 'US' },
{ full: 'Maine', abbr: 'ME', country: 'US' },
{ full: 'Maryland', abbr: 'MD', country: 'US' },
{ full: 'Massachusetts', abbr: 'MA', country: 'US' },
{ full: 'Michigan', abbr: 'MI', country: 'US' },
{ full: 'Minnesota', abbr: 'MN', country: 'US' },
{ full: 'Mississippi', abbr: 'MS', country: 'US' },
{ full: 'Missouri', abbr: 'MO', country: 'US' },
{ full: 'Montana', abbr: 'MT', country: 'US' },
{ full: 'Nebraska', abbr: 'NE', country: 'US' },
{ full: 'Nevada', abbr: 'NV', country: 'US' },
{ full: 'New Hampshire', abbr: 'NH', country: 'US' },
{ full: 'New Jersey', abbr: 'NJ', country: 'US' },
{ full: 'New Mexico', abbr: 'NM', country: 'US' },
{ full: 'New York', abbr: 'NY', country: 'US' },
{ full: 'North Carolina', abbr: 'NC', country: 'US' },
{ full: 'North Dakota', abbr: 'ND', country: 'US' },
{ full: 'Ohio', abbr: 'OH', country: 'US' },
{ full: 'Oklahoma', abbr: 'OK', country: 'US' },
{ full: 'Oregon', abbr: 'OR', country: 'US' },
{ full: 'Pennsylvania', abbr: 'PA', country: 'US' },
{ full: 'Rhode Island', abbr: 'RI', country: 'US' },
{ full: 'South Carolina', abbr: 'SC', country: 'US' },
{ full: 'South Dakota', abbr: 'SD', country: 'US' },
{ full: 'Tennessee', abbr: 'TN', country: 'US' },
{ full: 'Texas', abbr: 'TX', country: 'US' },
{ full: 'Utah', abbr: 'UT', country: 'US' },
{ full: 'Vermont', abbr: 'VT', country: 'US' },
{ full: 'Virginia', abbr: 'VA', country: 'US' },
{ full: 'Washington', abbr: 'WA', country: 'US' },
{ full: 'West Virginia', abbr: 'WV', country: 'US' },
{ full: 'Wisconsin', abbr: 'WI', country: 'US' },
{ full: 'Wyoming', abbr: 'WY', country: 'US' },
// Canadian Provinces and Territories
{ full: 'Alberta', abbr: 'AB', country: 'CA' },
{ full: 'British Columbia', abbr: 'BC', country: 'CA' },
{ full: 'Manitoba', abbr: 'MB', country: 'CA' },
{ full: 'New Brunswick', abbr: 'NB', country: 'CA' },
{ full: 'Newfoundland and Labrador', abbr: 'NL', country: 'CA' },
{ full: 'Nova Scotia', abbr: 'NS', country: 'CA' },
{ full: 'Ontario', abbr: 'ON', country: 'CA' },
{ full: 'Prince Edward Island', abbr: 'PE', country: 'CA' },
{ full: 'Quebec', abbr: 'QC', country: 'CA' },
{ full: 'Saskatchewan', abbr: 'SK', country: 'CA' },
{ full: 'Northwest Territories', abbr: 'NT', country: 'CA' },
{ full: 'Nunavut', abbr: 'NU', country: 'CA' },
{ full: 'Yukon', abbr: 'YT', country: 'CA' },
];
return states
.map(
(state) =>
`<option value="${state.abbr}" ${state.abbr === selectedState ? 'selected' : ''}>${state.full} (${state.abbr}) - ${
state.country === 'US' ? 'USA' : 'Canada'
}</option>`
)
.join('');
}
function getRandomName() {
const firstNames = ['John', 'Jane', 'Alex', 'Emily', 'Chris', 'Katie', 'Mike', 'Laura', 'David', 'Sarah'];
const lastNames = ['Smith', 'Johnson', 'Brown', 'Williams', 'Jones', 'Garcia', 'Miller', 'Davis', 'Rodriguez', 'Martinez'];