﻿id	summary	reporter	owner	description	type	status	priority	component	resolution	keywords	cc
1083	Переадресация на несуществующий URI	alx	Denis_N	"r162/base.

Открыл главную страницу на сервере !r2. Хочу посмотреть историю одного из отображаемых там изделий, для этого кликаю серийный номер этого изделия. В результате браузер пытается открыть URL...

 `http://localhost/index.php?error=1` !!! 

И, так как на моем компьютере нет сервера, браузер отображает сообщение об ошибке подключения. Каким образом и почему браузер вдруг пошел на localhost вместо !r2?

В исходниках обнаружил два места, где фигурирует localhost (не считая комментариев):

- source:/base/orders.php@162:583#L580
- source:/base/lib/main.lib.php@162:423#L400

В первом из найденных файлов, насколько я понял, при клике какой-то кнопки выполняется такой код:

{{{#!javascript
  window.location.replace(""http://localhost/orders.php"");
}}}

Этот код неправильный сразу по нескольким причинам:

1. Метод `replace()` типа String требует два аргумента, а не один. Первый - что заменять, второй - на что заменять.
1. В качестве аргумента указан абсолютный URI ""http://localhost/orders.php"", при том что в реальной жизни неизвестно, на каком сервере и по какому пути у пользователя будет находиться требуемая страница (и уж наверняка это не будет localhost!). Код должен писаться таким образом, чтобы система была переносимой - то есть она должна работать как в случае, если orders.php находится на `http://localhost/orders.php`, так и на `https://localhost/orders.php`, и на `https://heaven.org/base/orders.php`, и на `https://hell.com:666/base/shmaze/my/favotite/long/path/orders.php`. То есть работа системы не должна зависеть ни от адреса сервера, ни от протокола, ни от номера порта, ни от пути к корневому каталогу наших файлов.
1. Если я правильно догадался, что идея была в том, чтобы просто перезагрузить страницу, то для этого достаточно было бы сделать `window.location = window.location`.

Во втором файле сервер внутри функции `error403()` возвращает HTML-код:

{{{#!xml
<meta http-equiv=""refresh"" content=""0; url=http://localhost/index.php?error='.$error.'"">
}}}

Очевидно, это и есть мой случай. :) Возникает сразу ряд вопросов:

- Почему вообще выполнилась `error403()`? У меня есть право на просмотр истории, и я аутентифицирован в системе (только что перед этим успешно получил список изделий на главной странице). Воспроизвелся баг #878?

- Почему здесь используется абсолютный URI? См. все, что написано выше об абсолютныз URI и переносимости.

- Наконец, выбран довольно странный метод переадресовать браузер на другой URL. Во-первых, `<meta/>` - это IMHO своеобразный ""костыль"", который может быть полезен в некоторых (экзотических) случаях. Например для сохранения Content-Type документа при его записи в файл (иначе при последующем чтении HTML-файла браузер не будет знать, как отобразить документ). В нашем же случае документ запрашивается с сервера, и нет никакого смысла перемещать поля из заголовка в meta http-equiv. В-третьих, для немедленной (у refresh стоит период 0!) переадресации протокол HTTP имеет специально для этого предназначенные средства - ответы 301/302/307. Рекомендую пользоваться ими.
"	дефект	closed	major	БД изделий АДС	fixed		
