PHP - redirigir https a http y www a no-www
**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.
Cómo redirigir HTTPS a HTTP y www a URL sin www con .htaccess:
Primero asegúrate de que
HTTPSesté 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
HTTPSaHTTP, recomendaría hacerlo al revés, es decir,HTTPaHTTPS. Mejor para Seguridad, SEO y compatibilidad con navegadores - los navegadores populares están haciendo cada vez más difícil que los sitiosHTTPfuncionen correctamente.Luego asegúrate de que
.htaccessy el módulomod_rewriteestén funcionando.Luego usa el siguiente CÓDIGO en el archivo
.htaccessdel 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.comcon 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é:
- Es más rápido.
- Tu archivo
functions.phppermanece más limpio y hace para lo que originalmente está ahí, es decir, modificaciones del Tema. - Cambiar el tema no afectará esto.
- 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.
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
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
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".
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
Esto quizás se deba a la configuración del sistema .htaccess. Intentaría probarlo en una ventana privada y buscar redirecciones ocultas.
Drupalizeme
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
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
@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
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
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.
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