Practical developers (dexSoft.ru)
Домены

Рейтинг

Метки

Сервис

Обсуждения

Марс атакует!
Сгинули все инопланетяне... Надоели мы им...

Статистика

 

Статьи > PHP

Контроль открытия документа вне фрейма

28 апрель 2009 15:50, рейтинг: 9238, автор: EloSoft

При использовании фреймов, всегда существует вероятность того, что страница, которая должна отображаться в одном из фреймов, будет открыта вне фрейма. Это создает неудобства как для пользователя, так и для владельца потому, что пользователь видит только часть страницы и, вполне возможно, не самую главную. Как проконтролировать во фрейме открыта страница или вне фрейма и как "вернуть" ее во фрейм?

Первый вопрос, который при этом возникает, где выполнять контроль – на сервере или на машине пользователя? Так хотелось написать все, ну скажем, на PHP, проверить все до отправки страницы и не использовать JavaScript, VBScript или что-то другое. В принципе на сервере можно организовать контроль и анализ запросов пользователя и логически определить, как пользователь пытается загрузить страницу, и, при необходимости, подкорректировать запросы, URL и т.п.. Но даже если Вам удастся реализовать подобный контроль, Вы будете лишь предполагать, в каком окне открыта страница, а не знать это. Реально узнать где открыта страница, изменить окно документа можно только на стороне пользователя. Поэтому не будем рассматривать экзотические способы и остановимся на использовании для этих целей JavaScript.

Наиболее практично проверить является ли окно документа верхним или проверить его имя. Будем считать, что фреймовая структура задается в файле myframe.html, а фрейм, в котором должен отображаться документ, имеет имя myFrame.

    Проверка подожения окна может выглядеть следующим образом:

// если проверяемое окно является верхним,
// то изменяем URL этого окна
< script language="JavaScript" type="text/javascript" >
if (window == top) {
  top.location.href = "myframe.html";
  // или window.location.href = "myframe.html"
}
< / script >


    Проверка имени окна может выглядеть следующим образом:

// если имя проверяемого окна не совпадает с именем нужного фрейма,
// то изменяем URL этого окна
< script language="JavaScript" type="text/javascript" >
if (this.name != "myFrame") {
// или if (self.name != "myFrame")
// или if (window.name != "myFrame")
  window.location.href = "myframe.html";
}
< / script >


Этот код надо вставить во все страницы, открытие которых вне фрейма не желательно. Выполнять такую проверку лучше всего внутри тега HEAD. Тогда, если потребуется перезагрузка документа, то она будет выполнена до того, как документ будет отображен на мониторе. Если это выполнять внутри тега BODY (например, по событию onLoad), то документ сначала будет показан, а потом начнется перезагрузка.

Для фреймов, в которых отображается всегда один и тот же документ этого вполне достаточно. Но обычно хотя бы в одном из фреймов могут отображаться разные документы и каждый раз при открытии этих документов вне фрейма отсылать пользователя в самое начало сайта нежелательно (например: пользователь пришел из поисковой системы на конкретную страницу, а вместо нее попадает на главную. В следующий раз он может просто проигнорировать Вашу ссылку). Значит необходимо указать какой именно документ должен отобразиться во фрейме. К тому же если такую проверку надо выполнять для многих документов, то вписывать скрипт в каждый из них не очень практично. Лучше создать отдельный файл скрипта и включать его в нужные документы.

Прежде чем создавать такой файл, оценим ситуацию в целом. Если все будет выполняться на стороне пользователя, то для того чтобы перезагрузить неправильно открытый документ потребуется не менее 2-х перезагрузок, прежде чем все окажется на своих местах (текущее окно > главное окно > установка нужного документа во фрейме). Это не очень хорошо. Вот здесь лучше всего совместить возможности серверных и клиентских скриптов, что позволит избежать лишних перезагрузок. Используем PHP и JavaScript. Все примеры скиптов просты и не требуют специальных пояснений. Необходимые комментарии будут даны в тексте примеров. 

Сначала зададим необходимые значения:
myframe.php – файл, содержащий описания фреймов;
dataFrame – имя фрейма, в котором должны отображаться документы;
mypage.php – один из документов;
mainpage.php - документ, отображаемый в dataFrame по умолчанию;
is_top.php – файл, содержащий скрипты контроля.

    Листинг файла is_top.php


Примечание: сначала, конечно, следует проверить, а нужно ли вообще перезагружать документ, но поскольку это зависит от конкретного сайта и конкретной ситуации, такая проверка здесь описываться не будет.


< ? php
$strQuery = "";
if ($_SERVER['PHP_SELF'] ==  "mypage.php") { 
  $strQuery = $_SERVER['PHP_SELF']; 
  if (isset($_SERVER['QUERY_STRING']) and $_SERVER['QUERY_STRING'] != "") {
    // если URL уже содержит какие-то запросы, 
    // то их надо включить в текст вновь создаваемого запроса 
    $strQuery .= "?curpage=".$_SERVER['QUERY_STRING']; 
  }
}
? >

< script language="JavaScript" type="text/javascript" >
if (window == top) { 
  top.location.href = "myframe.php";
}
< / script >

    Для вызова проверки достаточно включить в файл mypage.php одну строку (лучше всего делать проверку в самом начале документа, чтобы не выполнять ненужных действий, если будет выполнена перезагрузка документа).

    Листинг файла mypage.php

< ? php require_once('is_top.php'); ? >
// этот код надо вставить во все страницы, открытие которых вне фрейма не желательно
// далее текст документа

    Окончательная обработка производится в файле "myframe.php".

    Листинг файла myframe.php

< ? php
$curPage = "mainpage.php";
if (isset($_GET['curpage'])) {
  $curPage = (get_magic_quotes_gpc()) ? $_GET['curpage'] : addslashes($_GET['curpage']);
}
? >

< html >
...
  < frame src="" name="dataFrame" / >  
...
< /htm >

Примечание: для тех, кто использует какие-либо среды программирования для создания web-страниц (например, Macromedia Dreamweaver), предпочтительнее использовать немного другую конструкцию. Дело в том, что переменная $curPage при отображении страницы в дизайнере не определена. Это может вызвать ошибку или неправильное отображение документа. Вот такая конструкция исключает подобные проблемы:

< ? php
$curPage = "";
if (isset($_GET['curpage'])) {
  $curPage = (get_magic_quotes_gpc()) ? $_GET['curpage'] : addslashes($_GET['curpage']);
}
? >

< html >
...
< ? php if ($curPage == "") { ? >;
  < frame src="mainpage.php" name="dataFrame" / >
< ? php } else { ? >
  < frame src="" name="dataFrame" / >
< ? php } ? >
...< / html >


В этом случае Macromedia Dreamweaver в дизайнере страниц будет загружать в dataFrame документ "mainpage.php".


Файлы:

  1. Пример