Архив категории ‘Веб-строительство’

Оптимизация OpenCart

Кейс — тормозит сайт на OpenCart 1.5, а на сервер оказывается ощутимая нагрузка.
Проанализировав, что происходит при открытии страниц сайта, обнаружилось следующее.
При открытии любой страницы каталога происходят десятки однотипных SQL-запросов вида:
SELECT COUNT(DISTINCT p.product_id) AS total FROM oc_category_path cp LEFT JOIN oc_product_to_category p2c ON (cp.category_id = p2c.category_id) LEFT JOIN oc_product p ON (p2c.product_id = p.product_id) LEFT JOIN oc_product_description pd ON (p.product_id = pd.product_id) LEFT JOIN oc_product_to_store p2s ON (p.product_id = p2s.product_id) WHERE pd.language_id = '1' AND p.status = '1' AND p.date_available <= '2016-09-16 11:24:00' AND p2s.store_id = '0' AND cp.path_id = '721'
Эти запросы формируются функцией getTotalProducts, которая служит для подсчёта общего количества продуктов. Находится функция в файле catalog/model/catalog/product.php.

При открытии страниц каталога функция вызывается из файлов:
system/library/themeoptions.php
catalog/controller/common/header.php
catalog/controller/product/category.php

После отключения вызова функции в этих файлах (заменили строку $product_total = $product->getTotalProducts($data); на $product_total = 0;) сайт стал работать существенно быстрее, нагрузка на сервер снизилась в разы, а страницы стали открываться в 3-4 раза быстрее. На функционале сайта, на первый взгляд, ничего не изменилось - всё выглядит точно так же.

Поиск и удаление вредоносного кода, если он внедрён во множество файлов

Попался сайт с массово заражёнными файлами javascript. В конец каждого файла были дописаны две строки:
;document.write(unescape("%3C%73%63%72%69%70%74%20%74%79 ... далее много кода ... %73%63%72%69%70%74%3E%09"));
;var OOO='7kSKlBXYjNXZfhSZwF2YzV ... далее много кода ... ;eval(lI1(I11(OOO)));

Ищем в текущей директории файлы с расширением .js, внутри них ищем строку, начинающуюся на ;var OOO= и заканчивающуюся на eval(lI1(I11(OOO)));. Заменяем на пустую строку (двойной слэш).

find . -name "*.js" -type f -print0 | xargs -0 sed -i 's/;var OOO=.*eval(lI1(I11(OOO)));//g'

аналогично поступаем с первой строкой:

find . -name "*.js" -type f -print0 | xargs -0 sed -i 's/;document\.write(unescape("%3C%73%63%72%69.*%73%63%72%69%70%74%3E%09"));//g'

Переадресация (редирект) страниц с переменными

Если нужно сделать в .htaccess постоянную переадресацию со страницы с параметрами, передающимися после знака вопроса, на другую страницу (например, страниц, проиндексированных без ЧПУ, на страницы с ЧПУ), то обычный редирект работать не будет.
Вот обычный редирект:

Redirect 301 /folder/subfolder http://example.com/newfolder

Но если, к примеру, нам нужно переадресовать страницу вроде такой http://example.com/index.php?option=com_ex1&task=ex2&category_id=111&Itemid=222 на страницу http://example.com/newfolder, то придётся применять rewrite таким образом:

RewriteCond %{QUERY_STRING} ^option=com_ex1&task=ex2&category_id=111&Itemid=222$
RewriteRule ^index.php$ http://example.com/newfolder? [R=301,L]

Блокировка POST-запросов в .htaccess

С недавнего времени стали донимать боты-одиночки, которые непрерывно шлют POST-запросы на определённый URL, например:

111.111.111.111 - - [24/Mar/2013:11:28:01 +0300] "POST /edit HTTP/1.1" 404 13197 "http://example.com/" "Opera/9.80 (Windows NT 6.1) Presto/2.12.388 Version/12.14"

Лучше всего таких банить с помощью iptables, однако, если нет доступа к серверу, то с небольшим количеством ботов можно справиться и с помощью .htaccess:

RewriteCond %{REQUEST_URI} ^/edit$
RewriteCond %{REQUEST_METHOD} POST
RewriteRule ^ / [L,F]

В результате бот будет послан с ошибкой 403.
Здесь /edit — это страница сайта, к которой идут запросы.
Если боты ломятся на внутренние страницы, то мера будет такой:

RewriteCond %{REQUEST_METHOD} POST
RewriteRule .*/edit$ - [L,F]

Или универсальный метод, когда edit идёт и на главную, и на страницы:

RewriteCond %{REQUEST_METHOD} POST
RewriteRule ^(.*/)?edit$ - [L,F]

Редирект 301 в nginx

Простая переадресация в nginx с кодом 301 (перемещено постоянно) с домена с www на домен без www:

server {
  listen 80;
  server_name www.example.com;
  return 301 http://example.com$request_uri;
}

Соответственно, редирект с домена без www на www делается аналогично.

Решаем проблему с кодировкой страниц сайта

Браузер, открывая страницу, обычно берёт информацию о кодировке страницы либо из ответа веб-сервера, либо из информации на самой странице.
Поэтому, если у вас возникли какие-либо проблемы с отображением кодировок вашего сайта, следует проверить, какой заголовок отдаёт веб-сервер, включена ли в него информация о кодировке по умолчанию, а также проверить мета-теги страниц сайта на наличие в них информации о кодировке.
Проверить заголовок веб-сервера можно, воспользовавшись онлайн-сервисами, например этим, либо, в случае с linux, командой wget:

wget http://example.com -S -O /dev/null

Вот пример ответа веб-сервера:

  HTTP/1.1 200 OK
  Server: web-server
  Date: Tue, 20 Dec 2011 18:50:15 GMT
  Content-Type: text/html; charset=utf-8
  Connection: close
  Cache-Control: max-age=300
  Expires: Tue, 20 Dec 2011 18:55:17 GMT

Обратите внимание на слово charset. Оно-то и сообщает браузеру, что на данном сервере используется по умолчанию кодировка utf-8.
Если такого слова в ответе нет, заставить веб-сервер сообщать кодировку можно директивой в файле .htaccess, добавив в него строку:

AddDefaultCharset utf-8

В данном случае веб-сервер станет сообщать о кодировке utf-8. Другая весьма распространённая у нас кодировка — cp1251.

Второй способ сообщить браузеру о кодировке страницы — прописать информацию в мета-теге. Откройте исходник вашей страницы и посмотрите информацию между тегов <head>. Если информация о кодировке корректно записана в мета-теге, то вы должны будете увидеть строку вроде такой:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

Убрать лишний index.php из .htaccess

После переноса сайта с одного хостинга на другой пришлось столкнуться с проблемой, решение которой отняло чуть больше времени, чем обычно. Поэтому излагаю её здесь.

Суть проблемы:
Есть сайт на Joomla, включены ЧПУ, на новом хостинге всё функционирует отлично. Ссылки на сайте выглядят как http://site.by/section/category/
Но, будучи на старом хостинге, все страницы сайта чудесным образом проиндексировались поисковыми системами как http://site.by/index.php/section/category/
В результате, если заходить на сайт напрямую, то сайт красиво работает на новом хостинге. Однако, люди, заходящие из поисковиков, видят криво работающий сайт (не подгружаются css, вся графика и javascript). Не знаю, что было не так со старым хостингом, во время которого проходила индексация, но правила реврайтов для SEF .htaccess были стандартные для движка joomla:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/index.php
RewriteCond %{REQUEST_URI} (/|\.php|\.html|\.htm|\.feed|\.pdf|\.raw|/[^.]*)$  [NC]
RewriteRule (.*) /index.php
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]

В общем, ждать, пока поисковики заново проиндексируют весь сайт, как бы не тема, поэтому сработал вот такой вариант:

RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,L]

Эти 2 строки, помещённые перед секцией SEF в .htaccess, удаляют index.php из URL и делают постоянный редирект на URL, и приводит к стандартному виду ЧПУ Joomla.