es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Redirija solo una vez utilizando Cloudflare Worker.

Estoy tratando de implementar un sitio multilingüe en Gatsby y desplegarlo en Cloudflare pages. Necesito un trabajador que redirija a páginas específicas de cada país.

Ejemplo: La URL de mi sitio es example.com. Si el usuario está visitando desde India, necesito que se redirija a example.com/in/. Si es de Japón, debe redirigirse a example.com/jp/.

He escrito un Trabajador de la siguiente manera:

const base = BASE_URL;
const statusCode = 301;

const getPrefix = (request) => {
    const countryCode = request?.cf?.country;
    const continent = request?.cf?.continent;
    let prefix = "";

    if (countryCode === "JP") {
        prefix = "/jp/";
    } else if (countryCode === "IN") {
        prefix = "/in/";
    }

    return prefix;
};

function handleRequest(request) {
    const url = new URL(request.url);
    let { pathname, search, hash } = url;

    const prefix = getPrefix(request);
    if (prefix === "" || pathname.indexOf(prefix) === 0) {
        return fetch(request);
    }

    pathname = pathname.replace("/", prefix);
    const destinationURL = base + pathname + search + hash;
    return Response.redirect(destinationURL, statusCode);
}

addEventListener("fetch", async (event) => {
    event.respondWith(handleRequest(event.request));
});

Con esto, la redirección mencionada anteriormente está ocurriendo correctamente.


Requisito adicional

También necesito permitir a los usuarios ver el sitio global (example.com) sin rutas específicas de cada país si así lo desean. Si el usuario hace clic en el hipervínculo para visitar la versión global del sitio, el trabajador aún redirige, lo cual no deseo que suceda.

O en otros términos, si ya se ha redirigido, el trabajador no debería redirigir nuevamente.

Restricción: no se puede agregar otra ruta como ejemplo.com/gb/ para la versión global. Debe ser la ruta raíz misma.

¿Existe alguna forma de manejar este requisito? Por favor, sugiéralo.

Gracias de antemano.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para manejar este requisito, podemos utilizar cookies. Cuando un usuario hace clic en el hipervínculo para visitar la versión Global del sitio, el worker puede establecer una cookie en la respuesta para indicar que el usuario ha elegido explícitamente ver la versión Global.

    Luego, cuando llega una solicitud posterior con la cookie establecida, el worker puede omitir la lógica de redirección y servir directamente la versión Global.

    Aquí tienes un código de worker actualizado que implementa esta lógica:

    const base = BASE_URL;
    const statusCode = 301;
    const GLOBAL_COOKIE_NAME = 'global_version';
    
    const getPrefix = (request) => {
        const countryCode = request?.cf?.country;
        const continent = request?.cf?.continent;
        let prefix = "";
    
        if (countryCode === "JP") {
            prefix = "/jp/";
        } else if (countryCode === "IN") {
            prefix = "/in/";
        }
    
        return prefix;
    };
    
    function handleRequest(request) {
        const url = new URL(request.url);
        let { pathname, search, hash } = url;
    
        const prefix = getPrefix(request);
    
        // Comprobar si el usuario ha elegido explícitamente ver la versión Global
        const globalCookie = request.headers.get('cookie')?.includes(`${GLOBAL_COOKIE_NAME}=true`);
    
        if (globalCookie) {
            return fetch(request);
        }
    
        if (prefix === "" || pathname.indexOf(prefix) === 0) {
            return fetch(request);
        }
    
        // Establecer la cookie para permitir a los usuarios ver la versión Global
        const response = Response.redirect(base + pathname + search + hash, statusCode);
        response.headers.append('Set-Cookie', `${GLOBAL_COOKIE_NAME}=true`);
    
        return response;
    }
    
    addEventListener("fetch", async (event) => {
        event.respondWith(handleRequest(event.request));
    });
    

    En el código anterior, primero comprobamos si la cookie global_version está establecida en los encabezados de la solicitud. Si lo está, omitimos la lógica de redirección y devolvemos la página solicitada directamente.

    Si la cookie no está establecida y la página solicitada necesita ser redirigida, establecemos la cookie global_version en los encabezados de respuesta antes de enviar la respuesta de redireccionamiento.

    De esta manera, las solicitudes posteriores del mismo usuario con la cookie establecida podrán acceder a la versión Global sin ser redirigidas.

Comments are closed.