Перенаправление Cloudflare Worker GeoIP с совпадающим URL и резервным вариантом

Я слежу за этим шаблоном: https://developers.cloudflare.com/workers/examples/country-code-redirect

По сути, я хотел бы перенаправить корневой домен, а также сопоставить URL-адрес.

Пример:

domain.com = ›en.domain.com

domain.com/some-page = ›en.domain.com/some-page

Я также пытаюсь установить резервный URL-адрес на случай, если код страны не совпадает. Таким образом, любые коды стран, которые я не установил, будут перенаправлены на en.domain.com. Я планирую сопоставить много разных кодов стран с URL-адресами их соответствующих языков.

Необходимо, чтобы США и другие англоязычные страны направляли на en.domain.com, а затем для других языков / стран были установлены соответствующие пути к субдоменам. Вот что я делал, но не понимал правильно:

addEventListener('fetch', event => {
    event.respondWith(handleRequest(event));
});


const handleRequest = async (event) => {
    
    const {request} = event
    const country = request.cf.country
    const url = new URL(request.url)
    const {hostname, pathname, protocol} = url
    
    const countryMap = {
        US: 'en',
        FR: 'fr',
        ES: 'es',
        PA: 'es'
    }
        
    if(country)
    {
        const lang = countryMap.hasOwnProperty(country) ? countryMap[country] : 'en'
        const newHostName = `${lang === 'en' ? '' : lang + '.'}${hostname}`
        
        //en = example.com
        //fr = fr.example.com
        //es = es.example.com
        //pa = es.example.com
        
        if(hostname !== newHostName)
        {
            const redirectUrl = new URL(pathname, `${protocol}//${newHostName}${pathname}`)
            
            return Response.redirect(redirectUrl.href, 301)
        }
        
    }
    
    return await fetch(request)
}

Любая помощь в достижении этой цели будет принята с благодарностью. Заранее спасибо!


person Lucas    schedule 25.03.2021    source источник
comment
Просто чтобы проверить, удалось ли вам заставить его работать с предоставленным мной кодом? Пожалуйста, отметьте как ответ, если он соответствует вашим требованиям. Спасибо!   -  person Ked Mardemootoo    schedule 05.06.2021


Ответы (1)


Вы видите, работает ли это для вас?

Я пробовал это со своей стороны, и он удовлетворяет вашим требованиям.

addEventListener('fetch', event => {
    event.respondWith(handleRequest(event.request))
})


async function handleRequest(request) {
    const country = request.headers.get('cf-ipcountry')

    // Define redirections
    const languageRules = new Map([
        ["ES", 'es'],
        ["PA", 'es'],
        ["FR", 'fr']
    ])
    
    //Get value from key
    const languageCode = languageRules.get(country)

    // Redirect to language subdomain for custom countries set
    if (languageCode) {
        const root = ".domain.com"
        const url = new URL(request.url)
        const path = url.pathname
        const protocol = url.protocol
        const destinationDomain = protocol + "//" + languageCode + root + path
        return Response.redirect(destinationDomain, 301)
    }        
    
    // Redirect to english domain for any other country
    else {
        const root = "en.domain.com"
        const url = new URL(request.url)
        const path = url.pathname;
        const protocol = url.protocol
        const destinationDomain = protocol + "//" + root + path
        return Response.redirect(destinationDomain, 301)
    }

    // Process request and return response
    const response = await fetch(request)
    return response
}
person Ked Mardemootoo    schedule 29.05.2021