PHP - редирект с https на http и с www на без www

20 нояб. 2017 г., 18:04:06
Просмотры: 11.9K
Голосов: 4

**РЕДАКТИРОВАНИЕ: В итоге я разобрался. Прокрутите вниз до моего собственного ответа (отмечен зеленой галочкой)**

Сейчас я использую functions.php для перенаправления URL с https на http для сайта, у которого пока нет SSL-сертификата:

function shapeSpace_check_https() {
    // Проверяем, используется ли HTTPS или порт 443
    if ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443) {
        return true;
    }
    return false;
}

function bhww_ssl_template_redirect() {
    // Если используется HTTPS
    if (shapeSpace_check_https()) {
        if (0 === strpos($_SERVER['REQUEST_URI'], 'http')) {
            // Перенаправляем с HTTPS на 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');

В этой же функции я хотел бы добавить перенаправление с поддомена www на адрес без www. Я нашел хорошую функцию здесь, но мне нужна помощь с её интеграцией в мою текущую функцию. Я бы хотел избежать реализации этого в .htaccess, но буду рад и такому решению.

3
Комментарии

Для перенаправления с https на http сначала необходимо иметь действительный SSL-сертификат для выполнения первоначального рукопожатия, а затем уже делать перенаправление.

Drupalizeme Drupalizeme
20 нояб. 2017 г. 18:57:42

С помощью приведенной выше функции я успешно перенаправляю с https на http. Недостаток в том, что пользователь все равно видит пугающее сообщение браузера о недействительном SSL-сертификате. Пока я с этим могу смириться — но у меня возникли сложности с перенаправлением с www на версию без www с помощью preg_replace(). Мне нужно добавить оператор "или" где-то вроде 'https:// | https://www.'

Kyle Vassella Kyle Vassella
20 нояб. 2017 г. 19:10:47

Можно попробовать такой вариант: $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 нояб. 2017 г. 19:20:41
Все ответы на вопрос 4
2

Как перенаправить HTTPS на HTTP и www на non-www URL с помощью .htaccess:

  1. Сначала убедитесь, что HTTPS работает и действителен. Это легко (и бесплатно) сделать с помощью Let's Encrypt в наше время.

    Примечание: Хотя вы перенаправляете HTTPS на HTTP, я рекомендую делать наоборот, т.е. HTTP на HTTPS. Лучше для безопасности, SEO и совместимости с браузерами — популярные браузеры всё чаще усложняют работу сайтам на HTTP.

  2. Затем убедитесь, что .htaccess и модуль mod_rewrite работают.

  3. Затем используйте следующий КОД в файле .htaccess вашего корневого веб-каталога (если вы уже используете там какие-либо правила, адаптируйте их соответственно с этими новыми правилами):

    <IfModule mod_rewrite.c>
        RewriteEngine On
    
        RewriteCond %{HTTPS}        =on   [OR]
        RewriteCond %{HTTP_HOST}    !^example\.com$
        RewriteRule ^(.*)$          "http://example.com/$1" [R=301,L]
    
        # оставшийся htaccess mod_rewrite КОД для WordPress
    </IfModule>
    

    Примечание: Замените example.com на ваше собственное доменное имя.


Почему решение с .htaccess лучше:

Лучше делать такие перенаправления на уровне веб-сервера. Из вашего вопроса, поскольку ваш веб-сервер, похоже, Apache, лучше сделать это через .htaccess. Почему:

  1. Это быстрее.
  2. Ваш файл functions.php остаётся чище и делает то, для чего он изначально предназначен, т.е. модификации темы.
  3. Смена темы не повлияет на это.
  4. Для каждого перенаправления не нужно загружать всю кодовую базу WordPress дважды — один раз до перенаправления и затем после перенаправления.
23 нояб. 2017 г. 11:48:07
Комментарии

Спасибо за это. Я попробовал, но почему-то изменения в .htaccess не вступают в силу (я пробовал ваш способ и другие). Интересно, нужно ли мне что-то перезапустить, чтобы заставить это работать.

Kyle Vassella Kyle Vassella
27 нояб. 2017 г. 15:43:26

Прежде всего, если вы не установите HTTPS (SSL) должным образом, то правила .htaccess для HTTPS могут вообще не работать (я уже писал об этом в своем ответе). Также вы должны убедиться, что .htaccess действительно работает на вашем сайте, потому что если это так, перезапуск не должен требоваться.

Fayaz Fayaz
28 нояб. 2017 г. 04:29:41
5

Взят из вашего кода, я бы рефакторил его следующим образом:

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(); 
    }
}

Добавьте правила в .htaccess для редиректа www -> non-www

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

Редирект https -> http

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

Но опять же, для работы этого требуется наличие валидного SSL-сертификата, иначе пользователям будет показан "Экран ужаса".

20 нояб. 2017 г. 19:34:00
Комментарии

Большое спасибо, что нашли время помочь. К сожалению, www не удаляется из адресной строки в моем случае - похоже, перенаправление не работает. Я исправил опечатку с лишней 'w' в 'https://wwww' в вашем коде, а также попробовал вариант с if(strpos($url, $types) !==0) вместо вашего ===0, так как подумал, что в этом может быть проблема, но ничего не вышло. Буду продолжать разбираться, что можно изменить. Если у вас есть идеи, пожалуйста, дайте знать.

Kyle Vassella Kyle Vassella
20 нояб. 2017 г. 21:21:43

Возможно, это связано с настройками системы в файле .htaccess. Попробуйте проверить в приватном окне и поищите скрытые перенаправления.

Drupalizeme Drupalizeme
21 нояб. 2017 г. 06:03:07

Спасибо, что вернулись к этому вопросу. Я пробовал разные методы в .htaccess, включая ваш, но изменения не применяются - думаю, может потребоваться деактивировать и снова активировать тему WordPress, чтобы изменения в .htaccess вступили в силу, но я пока не готов на этот шаг (никогда этого не делал). Поэтому продолжу работать с PHP - пока ничего не получается. Ваш способ успешно перенаправляет с https на http, но мне все еще не удается убрать поддомен www. Я проверил в приватном окне и не увидел скрытых перенаправлений во вкладке Network (если это правильный способ проверки) - только ожидаемый редирект с https на http с кодом 301.

Kyle Vassella Kyle Vassella
21 нояб. 2017 г. 22:17:46

Я заметил, что после вашего оператора if else вы использовали сокращенную форму if: $redirect_url = !empty($redirect_url)?$redirect_url:$url;, но $url не определен глобально здесь - он определен только в операторе if. Не уверен, является ли это причиной или нет - возможно, $url определен глобально в PHP, или он не нужен в любом случае?

Kyle Vassella Kyle Vassella
21 нояб. 2017 г. 22:24:29

@KyleVassella 1) Переменная $url не должна объявляться глобально, так как она служит только для локальной области видимости оператора if. Она содержит $_SERVER['REQUEST_URI'] и должна учитываться, если $redirect_url остается пустой. 2) Файл .htaccess должен работать как есть, без активации/деактивации тем. Но есть большое "если": это может измениться, если есть кэширование или что-то еще, что мешает работе правил. Я бы попробовал поместить правила в начало файла .htaccess.

Drupalizeme Drupalizeme
22 нояб. 2017 г. 07:57:46
1

Спасибо всем за помощь. Но следующий код — это то, что в итоге сработало для меня, чтобы сделать 301 редирект с https на http и с www на без www. Я разместил следующий блок кода внутри functions.php:

//проверяем, используется ли https, независимо от сертификата
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++) {
    //если 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;
    //если только 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;
    //если только https://
    } elseif ( shapeSpace_check_https() ) {
            header('HTTP/1.1 301 Moved Permanently');
            header('Location: http://' . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
            exit;
            break;
    }
}

Не думаю, что мне нужны break;, но точно нужны exit;, и я оставил break; на всякий случай. Пожалуйста, объясните, почему мне, возможно, не нужны оба. Приведённый выше код приводит к следующим редиректам:

https://www.example.com на http://example.com

https://example.com на http://example.com

http://www.example.com на http://example.com

27 нояб. 2017 г. 17:39:26
Комментарии

Спасибо. Это работает.

Faisal Ramzan Faisal Ramzan
15 авг. 2021 г. 20:22:09
1

Вот обновленная функция для перенаправления с www на без 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(); 
    }
}

Дайте знать, если это поможет.

23 нояб. 2017 г. 12:47:34
Комментарии

Спасибо, что уделили время. Я не пробовал ваш способ, так как уже сделал свою рабочую версию. Я бы попробовал, но в тот момент не мог рисковать снова сломать работающий сайт. Ваш способ может работать, хотя навскидку мне кажется, что он не будет перенаправлять http://www.example.com на http://example.com, поскольку вся логика находится внутри if (shapeSpace_check_https() ), который, как я понимаю, проверяет использование https. Хотя я могу ошибаться.

Kyle Vassella Kyle Vassella
27 нояб. 2017 г. 17:51:26