Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Язык структурированных запросов и основы web-программирования. Учебное пособие
.pdf
Атрибут async определяет асинхронную работу скрипта, т. е. браузер не останавливает обработку html-документа в ожидании загрузки
скрипта. Скрипт выполнится, когда завершится его загрузка.
Атрибут defer определяет выполнение скрипта после загрузки htmlдокумента.
Основы программирования на языке JavaScript приводятся по адресу: https://learn. javascript.ru/first-steps.
Язык JavaScript позволяет работать с загруженным htmlдокументом, отображаемым в окне браузера посредством DOM
(Document Object Model – объектная модель документа), с браузером –
посредством BOM (Browser Object Model – объектная модель браузера). Кроме того, есть объекты, поддерживаемые непосредственно
JavaScript (рис. 2.12).
Рис. 2.12. Иерархия объектов DOM, BOM и JavaScript
Как видно из рис. 2.12, в вершине иерархии объектов находится
объект window.
Рассмотрим более подробно работу с объектной моделью документа (DOM). Модель DOM строится в полном соответствии со структурой html-документа.
Структура html-документа и соответствующая ей объектная модель
документа приведены на рис. 2.13.
В соответствии с DOM html-документ представляется в виде дерева, состоящего, как правило, из узлов двух типов: узел-элемент и узелтекст.
51

<html>
<head>
<title>
Название html-документа
</title>
Заголовок html-документа
</head>
<body>
Тело html-документа
</body>
</html>
а б
Рис. 2.13. Структура (а) и DOM (б) html-документа
head
title
Название
html
Заголовок
body
Тел о
Каждому тегу html-документа в дереве DOM соответствует узелэлемент, вложенные теги становятся дочерними узлами (на рис. 2.13
узлы-элементы представлены прямоугольниками). Текстовое содержимое тегов соответствует узлам-текстам (на рис. 2.13 узлы-тексты
представлены овалами).
Всего стандартом определено 12 типов узлов (https://www.w3.org/
TR/DOM-Level-3-Core), но узел-элемент и узел-текст используются
чаще других.
Если при создании документа не были выдержаны требования
стандарта относительно структуры документа, браузер автоматически
внесет нужные исправления. Например, в html-документ, в котором
отсутствуют теги <html>, <head> и <body>, они будут добавлены для
построения правильного дерева DOM (рис. 2.14).
Рис. 2.14. Исправленная структура html-документа
52

Изменение дерева DOM и его узлов с помощью программы на языке JavaScript меняет html-документ, отображаемый браузером.
Для работы с деревом DOM в языке JavaScript существуют разные
методы, которые рассмотрим далее.
Метод getElementById() позволяет получить доступ к произвольному элементу html-документа, указав в качестве входного параметра
id элемента. Например, в коде, приведенном ниже, с помощью метода
getElementById() выполняется доступ к нумерованному списку, размеченному тегом <ol> с атрибутом id = "list".
<ol id = "list">
<li>HTML</li>
<li>CSS</li>
</ol>
<script>
alert(document.getElementById("list").tagName)
</script>
Получив доступ к произвольному элементу html-документа, можно
получить доступ и к элементам-соседям текущего элемента, используя
свойства parentNode, previousSibling, nextSibling, firstChild,
childNodes[i], lastChild (рис. 2.15).
Node.parentNode
Текущий узел NodeNode.previousSibling Node.nextSibling
Node.firstChild Node.childNodes[i] Node.lastChild
Рис. 2.15. «Соседи» текущего узла
Например, можно получить доступ к тегу <li> с атрибутом
id = "css", а затем, используя свойства previousSibling и nextSibling, получить доступ к другим пунктам списка, также размеченным тегами
<li>, которые являются «братьями» для тега <li> с атрибутом id = "css".
Свойства parentNode и childNodes[] позволяют получить доступ к тегам <ol> и <i>, являющимся «родителем» и «ребенком» для тега <li>
с атрибутом id = "css".
53

<ol id = "list">
=
<li id = "html">HTML</li>
<li id = "css"><i>CSS</i></li>
<li id = "js">JavaScript</li>
</ol>
<script>
elem = document.getElementById("css")
alert(elem.previousSibling.tagName)
alert(elem.parentNode.tagName)
alert(elem.childNodes[0].tagName)
alert(elem.nextSibling.tagName)
</script>
Следует отметить, что некоторые браузеры трактуют символы пробелов и переходов на новую строку как узлы-тексты, что вызывает
проблемы при использовании свойств firstChild, lastChild, nextSibling,
previousSibling. В частности, в коде, приведенном выше, для его корректной работы в любом браузере следует записать весь тег <ol> одной
строкой.
Методы createElement(), createTextNode(), appendChild(), insertBefore(),
removeChild() позволяют создавать новые узлы и добавлять их в дерево
DOM, а также удалять существующие узлы. Например, в коде, при-
веденном ниже, слева к тегу <ol> с атрибутом id = "list" добавляется
новый «ребенок», т. е. новый последний пункт списка – тег
<li>JavaScript</li>. Справа выполняется обратное действие – удаляется
существующий «ребенок» тега <ol> – тег <li>JavaScript</li>.
<ol id = "list">
<li>HTML</li>
<li>CSS</li>
</ol>
<script>
elem = document.getElementById("list")
newItem = document.createElement("LI")
newText = document.createTextNode
("JavaScript")
newItem.appendChild(newText)
elem.appendChild(newItem)
</script>
<ol id
"list">
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ol>
<script>
elem = document.getElementById("list")
elem.removeChild(elem.lastChild)
</script>
Методы createAttribute(), setAttribute(), removeAttribute(), getAttrib-
ute() позволяют создавать и работать с атрибутами узлов дерева DOM.
Например, в коде ниже выполняется работа с атрибутом align тега <p>
с атрибутом id="attr". Кликнув по той или иной кнопке, можно добавить, изменить или удалить атрибут align тега <p>.
54

<p id = "attr">Текст</p>
<button onclick = "document.getElementById('attr').createAttribute('align')">Create</button>
<button onclick = "document.getElementById('attr').setAttribute('align','center')">Set</button>
<button onclick = "alert(document.getElementById('attr').getAttribute('align'))">Get</button>
<button onclick = "document.getElementById('attr').removeAttribute('align')">Remove</button>
Свойства innerHTML и outerHTML дают возможность работать
с содержимым узлов-элементов и изменять их.
Свойство innerHTML позволяет получить доступ к содержимому
узла-элемента как к строке. Это свойство доступно по чтению и по записи. Например, в коде, приведенном ниже, сначала в модальном окне
выводится первоначальное содержимое тега <body>, которое затем
заменяется новым содержимым.
<body>
<h1>Заголовок</h1>
<p>Текст</p>
<script>
alert(document.body.innerHTML)
document.body.innerHTML = "<h2 style = 'font-style:italic'>Заголовок"
</script>
</body>
Если в новом значении свойства innerHTML будет допущена
ошибка, то браузер скорректирует ее. Так, в коде, приведенном выше,
не был закрыт тег </h2> в новом значении свойства innerHTML для
тега <body>. В итоге после выполнения кода в браузере можно увидеть, что тег закрыт.
Свойство outerHTML по сравнению со свойством innerHTML позволяет получить доступ ко всему узлу-элементу в целом – к тегу и его
содержимому как к единой строке. Свойство outerHTML доступно по
чтению и по записи. В коде, приведенном ниже, сначала в модальном
окне выводится тег <div> и его первоначальное содержимое, которое
затем заменяется тегом <h3>.
<body>
<div id = "elem">
<h1>Заголовок</h1>
<p>Текст</p>
<script>
alert(elem.outerHTML);
55

elem.outerHTML = "<h3 style = 'color:red'>Заголовок</h3>";
</script>
</div>
...
</body>
В следующем коде формируется документ с перечнем гиперссылок.
<p id=list></p>
<script>
links = new Array('nstu.ru', 'nsu.ru')
texts = new Array('НГТУ', 'НГУ')
for (i = 0; i < links.length; i++)
{
link = document.createElement('a')
link.setAttribute('href', 'http://' + links[i])
text = document.createTextNode(texts[i])
link.appendChild(text)
elem = document.getElementById('list')
elem.appendChild(link)
br = document.createElement('br')
elem.appendChild(br)
}
</script>
В коде, приведенном далее, кликнув на изображении, можно заменить это изображение на новое, повторный клик восстанавливает
исходное изображение.
<img id = "img" src = "1.jpg" onclick = "changeImg()">
<script>
ind = 1
function changeImg()
{
elem = document.getElementById('img')
if (ind == 1)
{elem.src='2.jpg'; ind = 2}
else-
{elem.src='1.jpg'; ind = 1}
}
</script>
56

2.5. Общешлюзовой интерфейс
Общешлюзовой интерфейс Common Gateway Interface (CGI) –
стандартный способ для взаимодействия между web-сервером и исполняемым файлом на стороне сервера, создающим web-документ «на
лету». Такие исполняемые файлы называются CGI-скриптами и могут
быть написаны на любом языке программирования, хотя в настоящее
время пишутся на специализированном серверном скриптовом языке
(Java, Python, PHP, Ruby, PERL и проч.). На сайте IEEE Spectrum приведен рейтинг десяти наиболее популярных языков программирования,
в том числе серверных скриптовых языков, по состоянию на 2022 г.
(http://spectrum.ieee.org/top-programming-languages-2022).
Интерфейс CGI – это набор правил, в соответствии с которыми
web-сервер и CGI-скрипт обмениваются данными.
Интерфейс CGI использует переменные окружения и стандартные
потоки ввода/вывода. Таким образом, как уже упоминалось выше,
CGI-скрипт может быть написан на любом языке программирования,
имеющем средства для работы с переменными окружения и стандартными потоками ввода/вывода.
Передача данных от web-сервера CGI-скрипту зависит от метода,
которым был передан запрос клиента. Непосредственно для определения CGI-скриптом метода запроса клиента используется переменная
окружения REQUEST_METHOD.
В случае GET-запроса клиента данные, переданные в запросе, CGIскрипт может получить, прочитав значение переменной окружения
QUERY_STRING.
В случае POST-запроса клиента в переменной окружения
CONTENT_LENGHT хранится объем данных в байтах, присланных
клиентом в запросе. Получить данные можно из стандартного потока
ввода.
Для передачи данных от CGI-скрипта web-серверу используется
стандартный поток вывода.
Рассмотрим универсальный CGI-скрипт, позволяющий получать
данные как из GET-запроса, так и из POST-запроса.
Данные CGI-скрипт получает из html-формы, отображаемой на
стороне клиента.
57

<form action="/cgi/hello.exe" method="get"> <!-- или method="post" -->
Имя <input type="text" name="name">
Возраст <input type="text" name="age">
<input type="submit">
</form>
CGI-скрипт распознает метод запроса (прочитав значение переменной окружения REQUEST_METHOD) и принимает данные, присланные
в запросе. В случае метода GET данные можно получить, прочитав значение переменной окружения QUERY_STRING. В случае метода POST
в переменной CONTENT_LENGTH хранится количество байтов, присланных в теле запроса. Непосредственно данные можно получить из
стандартного потока ввода. Вне зависимости от метода запроса результат работы CGI-скрипта направляется в стандартный поток вывода.
void main()
{
string request_method = getenv("REQUEST_METHOD"); // определение метода
if (request_method == "GET")
{
string query_string = getenv("QUERY_STRING"); //чтение данных GET-запроса
cout << "Content-type: text/html\n\n"; //заголовок ответа сервера
cout << "<html>QUERY_STRING = " << query_string << “</html>"; // html-документ
}
if (request_method == "POST")
{
int content_length = atoi(getenv("CONTENT_LENGTH")); //число байт
string data;
cin >> data; //чтение данных POST-запроса
cout << "Content-type: text/plain\n\n"; //заголовок ответа сервера
cout << "CONTENT_LENGTH = " << content_length << endl; // текстовый документ
cout << "DATA = " << data;
}
}
Скрипт может сформировать документ любого медиа-типа. В коде,
приведенном выше, формируются документы двух типов: html-документ (text/html) и текстовый документ (text/plain). Так как возможен
любой медиа-тип формируемого документа, в CGI-скрипте необходимо
сформировать один заголовок ответа сервера – Content-type. В ответе
58

сервера заголовки должны быть отделены от тела запроса пустой строкой, и CGI-скрипт должен обеспечить это разделение.
На рис. 2.16 приведены исходная форма и результаты работы CGIскрипта для разных методов запросов.
а б
Рис. 2.16. Исходная форма (а) и результаты работы (б) CGI-скрипта
CGI-скрипт может дополнительно формировать любые заголовки
ответа сервера, например Set-Cookie, Location и др. Документ, сформированный CGI-скриптом и снабженный заголовком(-ами), принимает web-сервер, который окончательно формирует полный ответ сервера
и отсылает его клиенту.
В случае формирования CGI-скриптом полного ответа web-сервер
пересылает его клиенту без дополнений. Имя файла с CGI-скриптом,
формирующим полный ответ сервера, должно иметь префикс nph
(No Parsed Header).
На рис. 2.17 приведены код CGI-скрипта, формирующего полный
ответ сервера, и результат работы скрипта.
void main()
{
cout << "HTTP/1.1 500 Internal
Server Error\n\n";
}
Рис. 2.17. Формирование полного ответа сервера CGI-скриптом
59

2.6. Серверный скриптовый язык PHP.
Взаимодействие серверных скриптов с СУБД
с использованием языка запросов SQL
В отличие от скриптов, написанных на клиентском скриптовом
языке JavaScript и выполняющихся на стороне клиента в контексте
браузера после загрузки html-документа, скрипты, написанные на серверном скриптовом языке PHP, выполняются на стороне сервера перед
отправкой результатов их работы браузеру [17–20].
Скрипт, написанный на языке PHP, может сочетаться с htmlразметкой, при этом файл, содержащий html-разметку и php-скрипт,
как правило, имеет расширение *.php. В отличие от cgi-скриптов, для
размещения которых отводится определенный каталог, файлы с phpскриптами располагаются в том же каталоге, что и html-документы.
Для того чтобы иметь возможность писать серверные скрипты на
языке PHP, помимо web-сервера на серверной стороне должен быть
установлен интерпретатор PHP.
В настоящее время последней версией языка является PHP7. С момента своего появления в 1995 г. язык претерпел большие изменения,
однако сохранил главное: язык используется для создания динамических html-документов.
Программа (скрипт), написанная на PHP, располагается непосредственно в html-документе (при этом html-документ может вовсе не содержать html-разметки).
Для вставки скрипта в html-документ используется тег <?php ?>.
<!DOCTYPE HTML>
<html>
<head><meta charset = "utf-8"></head>
<body>
<p>PHP</p>
<?php phpinfo()?>
</body>
</html>
Приведенный ниже код решает ту же задачу, что и код из подраздела 2.5 (см. с. 58): принимает данные, присланные в запросе клиента,
обрабатывает их и возвращает сформированный html-документ.
60
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
