PHP - redirigir https a http y www a no-www

20 nov 2017, 18:04:06
Vistas: 11.9K
Votos: 4

**EDITADO: Finalmente encontré la solución. Desplázate hacia abajo para ver mi respuesta aceptada (marca de verificación verde) **

Actualmente estoy usando functions.php para redirigir URLs https a http para un sitio que actualmente no tiene certificado SSL:

function shapeSpace_check_https() { 
if ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443) {
    
    return true; 
}
    return false;
}


function bhww_ssl_template_redirect() {
if ( shapeSpace_check_https() ) {

    if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) {
    
        wp_redirect( preg_replace( '|^https://|', 'http://', $_SERVER['REQUEST_URI'] ), 301 );
        exit();
    } else {
            wp_redirect( 'http://' . $_SERVER['HTTP_HOST'] . 
$_SERVER['REQUEST_URI'], 301 );
            exit(); 
        }
    
    }

}

add_action( 'template_redirect', 'bhww_ssl_template_redirect');

En esta misma función, me gustaría también redirigir el subdominio www a no-www. Encontré una buena función aquí, pero necesito ayuda para implementarla en mi función actual. Preferiría evitar hacer esto en .htaccess, pero también aceptaría una solución para ese archivo.

3
Comentarios

Para redirigir de https a http primero necesitas tener un SSL válido para realizar el handshake inicial y luego hacer la redirección.

Drupalizeme Drupalizeme
20 nov 2017 18:57:42

Con la función anterior puedo redirigir exitosamente de https a http. La desventaja es que el usuario aún tiene que pasar por una advertencia del navegador que dice que no hay un certificado SSL válido. Por ahora estoy bien con eso - solo estoy luchando con redirigir un www a no-www usando preg_replace(). Necesito un operador 'or' ahí diciendo algo como 'https:// | https://www.'

Kyle Vassella Kyle Vassella
20 nov 2017 19:10:47

Puedes probar esto $url = $_SERVER['REQUEST_URI']; $redirect_url='' $not_allowed = array('https://wwww', 'https://'); foreach($not_allowed as $types) { if(strpos($url, $types) === 0) { $redirect_url = str_replace($types, 'http://', $url); } }

Drupalizeme Drupalizeme
20 nov 2017 19:20:41
Todas las respuestas a la pregunta 4
2

Cómo redirigir HTTPS a HTTP y www a URL sin www con .htaccess:

  1. Primero asegúrate de que HTTPS esté funcionando y sea válido. Es fácil (y gratuito) de hacer con Let's Encrypt hoy en día.

    Nota: Aunque estés redirigiendo HTTPS a HTTP, recomendaría hacerlo al revés, es decir, HTTP a HTTPS. Mejor para Seguridad, SEO y compatibilidad con navegadores - los navegadores populares están haciendo cada vez más difícil que los sitios HTTP funcionen correctamente.

  2. Luego asegúrate de que .htaccess y el módulo mod_rewrite estén funcionando.

  3. Luego usa el siguiente CÓDIGO en el archivo .htaccess del directorio raíz de tu web (si ya estás usando algunas reglas allí, ajústalas según corresponda con estas nuevas reglas):

    <IfModule mod_rewrite.c>
        RewriteEngine On
    
        RewriteCond %{HTTPS}        =on   [OR]
        RewriteCond %{HTTP_HOST}    !^example\.com$
        RewriteRule ^(.*)$          "http://example.com/$1" [R=301,L]
    
        # código restante de htaccess mod_rewrite para WordPress
    </IfModule>
    

    Nota: Reemplaza example.com con tu propio nombre de dominio.


Por qué la solución con .htaccess es mejor:

Es mejor hacer este tipo de redirecciones con el servidor web. Según tu pregunta, ya que tu servidor web parece ser Apache, es mejor hacerlo con .htaccess. Por qué:

  1. Es más rápido.
  2. Tu archivo functions.php permanece más limpio y hace para lo que originalmente está ahí, es decir, modificaciones del Tema.
  3. Cambiar el tema no afectará esto.
  4. Por cada redirección, no es necesario cargar dos veces todo el código base de WordPress - una vez antes de la redirección y luego después de la redirección.
23 nov 2017 11:48:07
Comentarios

Gracias por esto. Lo he intentado, pero por alguna razón los cambios en .htaccess no surten efecto (he probado tu método y otros). Me pregunto si necesito reiniciar algo para forzar que funcione.

Kyle Vassella Kyle Vassella
27 nov 2017 15:43:26

En primer lugar, si no instalas HTTPS (SSL) correctamente, entonces las reglas de .htaccess para HTTPS pueden no funcionar en absoluto (ya lo he escrito en mi respuesta). Además, debes asegurarte de que .htaccess realmente está funcionando en tu sitio, porque si es así, no debería ser necesario reiniciar.

Fayaz Fayaz
28 nov 2017 04:29:41
5

Tomado de tu código, lo refactorizaría así:

function bhww_ssl_template_redirect() {
    $redirect_url='';
    if ( shapeSpace_check_https() ) {
        if ( 0 === strpos( $_SERVER['REQUEST_URI'], 'http' ) ) {
            $url = $_SERVER['REQUEST_URI'];

            $not_allowed = array('https://www', 'https://');
            foreach($not_allowed as $types) {
                if(strpos($url, $types) === 0) {
                    $redirect_url = str_replace($types, 'http://', $url); 
                } 
            }
        } else {
            $redirect_url ='http://' . $_SERVER['HTTP_HOST'] .  $_SERVER['REQUEST_URI'];
        }

            $redirect_url = !empty($redirect_url)?$redirect_url:$url;
            wp_redirect($redirect_url, 301 );
            exit(); 
    }
}

Añade estas reglas al .htaccess para la redirección www -> no www

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.tudominio.com [NC]
RewriteRule ^(.*)$ http://tudominio.com/$1 [L,R=301]

Redireccionando https -> http

RewriteEngine On
RewriteCond %{HTTPS} on
RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI}

Pero nuevamente, para que esto funcione necesitas tener un SSL válido o los usuarios verán la "pantalla de terror".

20 nov 2017 19:34:00
Comentarios

Muchas gracias por tomarte el tiempo de hacer esto. Desafortunadamente, el www no se está eliminando de la barra de direcciones en mi caso - no creo que esté redirigiendo. Eliminé el error tipográfico de la 'w' extra en 'https://wwww' en tu código, y también probé una versión con if(strpos($url, $types) !==0) en lugar de tu ===0 porque pensé que podría ser el problema, pero no pude hacerlo funcionar. Seguiré revisando para ver qué puedo cambiar. Si tienes alguna idea por favor házmelo saber.

Kyle Vassella Kyle Vassella
20 nov 2017 21:21:43

Esto quizás se deba a la configuración del sistema .htaccess. Intentaría probarlo en una ventana privada y buscar redirecciones ocultas.

Drupalizeme Drupalizeme
21 nov 2017 06:03:07

Gracias por volver a esto. He intentado hacer esto en .htaccess con tu método y otros, pero no logro que tenga efecto - creo que tal vez necesite desactivar y reactivar mi tema de WordPress para que los cambios en .htaccess surtan efecto, pero no estoy listo para dar ese paso (nunca lo he hecho). Así que me quedaré con PHP - todavía no puedo hacerlo funcionar. Tu método redirige exitosamente de https a http, pero aún no logro eliminar el subdominio www. Verifiqué en una ventana privada y no vi redirecciones ocultas en la pestaña Network (si así es como se verifica) - solo el esperado 301 de https -> http.

Kyle Vassella Kyle Vassella
21 nov 2017 22:17:46

Noté que después de tu declaración if else tenías la forma abreviada de if: $redirect_url = !empty($redirect_url)?$redirect_url:$url;, pero $url no está definido globalmente aquí - solo está definido en la declaración if. No estoy seguro si esa es la razón o no - tal vez $url está definido globalmente en PHP, o no es necesario de todos modos?

Kyle Vassella Kyle Vassella
21 nov 2017 22:24:29

@KyleVassella 1) La variable $url no es algo que deba declararse globalmente ya que solo sirve para el ámbito local de la declaración if. Contiene $_SERVER['REQUEST_URI'] y debe tenerse en cuenta si $redirect_url permanece vacío. 2) El .htaccess debería funcionar tal como está sin la activación/desactivación de temas. Pero hay un gran "si" esto podría cambiar si hay caché o algo más que interfiera con las reglas. Intentaría colocar las reglas al principio del .htaccess.

Drupalizeme Drupalizeme
22 nov 2017 07:57:46
1

Gracias a todos por su ayuda. Pero el siguiente código es lo que finalmente funcionó para mí para redirigir 301 de https a http y de www a no-www. Coloqué el siguiente bloque de código dentro de functions.php:

//verificar si se está usando https independientemente del certificado
function shapeSpace_check_https() { 
    if ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443) {
        return true; 
    }
    return false;
}


for ($x=0; $x<1; $x++) {
    //si https:// && www.
    if ( shapeSpace_check_https() && substr($_SERVER['HTTP_HOST'], 0, 4) === 'www.'){
            header('HTTP/1.1 301 Moved Permanently');
            header('Location: http://' . substr($_SERVER['HTTP_HOST'], 4).$_SERVER['REQUEST_URI']);
            exit;
            break;
    //si solo www.
    } elseif (substr($_SERVER['HTTP_HOST'], 0, 4) === 'www.') {
            header('HTTP/1.1 301 Moved Permanently');
            header('Location: http://' . substr($_SERVER['HTTP_HOST'], 4).$_SERVER['REQUEST_URI']);
            exit;
            break;
    //si solo https://
    } elseif ( shapeSpace_check_https() ) {
            header('HTTP/1.1 301 Moved Permanently');
            header('Location: http://' . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
            exit;
            break;
    }
}

No creo que necesite los break;, pero definitivamente necesito los exit; y dejé los break; por si acaso. Siéntete libre de explicarme por qué puede que no necesite ambos. El código anterior resulta en las siguientes redirecciones:

https://www.example.com a http://example.com

https://example.com a http://example.com

http://www.example.com a http://example.com

27 nov 2017 17:39:26
Comentarios

Gracias. Funciona.

Faisal Ramzan Faisal Ramzan
15 ago 2021 20:22:09
1

Aquí, usa esta función actualizada para redirigir un sitio con www a sin www:

function bhww_ssl_template_redirect() {
    $redirect_url='';
    $url = $_SERVER['REQUEST_URI'];
    if ( shapeSpace_check_https() ) {
        if ( 0 === strpos( $url, 'http' ) ) {
            if(strpos($url, 'https://') === 0) {
                $redirect_url = str_replace('https://', 'http://', $url); 
            } 
        } 
        elseif ( TRUE == strpos( $url, 'www.') ) {
             $redirect_url = str_replace('www.', '', $url); 
        } 
        else {
            $redirect_url ='http://' . $_SERVER['HTTP_HOST'] .  $_SERVER['REQUEST_URI'];
        }
            $redirect_url = !empty($redirect_url)?$redirect_url:$url;
            wp_redirect($redirect_url, 301 );
            exit(); 
    }
}

Déjame saber si esto te ayuda.

23 nov 2017 12:47:34
Comentarios

Gracias por tomarte el tiempo para hacer esto. No lo probé antes de que mi propia versión funcionara. Lo hubiera hecho, pero en ese momento no podía arriesgarme a romper el sitio en vivo nuevamente. Tu método podría funcionar, aunque de entrada no creo que redirija http://www.example.com a http://example.com ya que toda la lógica está dentro de if (shapeSpace_check_https() ), que creo que verifica si se está usando https. Podría estar equivocado, sin embargo.

Kyle Vassella Kyle Vassella
27 nov 2017 17:51:26