Огромный проект у нас впереди. Скоро мы будем делать менеджер шаблонов текста, который сможет хранить наши бесценные данные не локально на компьютере, а на сервере.
Для этого мы уже сделали рабочий прототип приложения, а потом разобрались с понятием JSON. Теперь попробуем отправить данные на сервер.
Как это устроено
Если мы хотим хранить данные на сервере и отправлять их туда в любой момент, нам нужно действовать так:
- Собрать данные в JSON-формат.
- Упаковать их в специальный запрос.
- Встроенными средствами JavaScript отправить этот запрос на сервер по нужному адресу.
- Чтобы наш запрос был принят, по этому адресу на сервере должен находиться скрипт, который умеет работать с такими запросами.
- А чтобы сервер в принципе отвечал на какие-то запросы, нам нужно его этому обучить.
Первые три пункта сделаем на клиенте — нашей HTML-странице, а скрипт и настройки — на сервере. Скрипт будем писать на PHP, поэтому, если не знаете, что это и как с этим работать, — почитайте.
Чтобы было проще, мы отправим и обработаем на сервере совсем маленький JSON — в нём всего две пары «имя: значение», но даже со сложным запросом всё будет работать так же.
Готовим HTML-страницу
У нас будет очень простая страница, потому что самое важное сейчас — научиться работать с JSON-форматом, а красоту наведём позже.
На странице нам понадобятся:
- заголовок;
- два поля ввода, чтобы вы могли ввести туда любые данные и убедиться, что отправка работает;
- кнопка, которая отправляет JSON на сервер;
- место для вывода результата — там мы выведем то, что пришлёт нам сервер в ответ.
Мы сразу подключим jQuery, чтобы в скрипте напрямую обращаться к полям ввода и месту для вывода результата. А ещё заранее зададим синий цвет для вывода ответа от сервера — так мы сразу отличим данные на странице от того, что нам ответил сервер.
На языке HTML это будет так:
<!DOCTYPE html>
<html>
<head>
<title>
Отправляем JSON-данные на сервер
</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body style="text-align:center;" id="body">
<!-- заголовок -->
<h1> Простая форма для проверки работы JSON </h1>
<!-- делаем форму с полями ввода -->
<p>
<input type="text" id="name" placeholder="Ваше имя">
<input type="text" id="lastname" placeholder="и фамилия">
<!-- по нажатию на эту кнопку данные уйдут на сервер -->
<button onclick="sendJSON()">Проверить JSON</button>
<!-- а вот тут они появятся снова, но уже после обработки сервером -->
<p class="result" style="color:blue"></p>
</p>
</body>
</html>
Отправляем данные на сервер
Обычно, чтобы отправить данные на сервер, нужно делать запрос. Вы нажимаете кнопку на странице, браузер уходит думать, ждёт ответа сервера и рисует вам новую страницу в соответствии с этим ответом. Грубо говоря, запрос на сервер заставляет вашу страницу перезагружаться.
К счастью, инженеры давно придумали, как отправлять данные на сервер, не перезагружая страницу. Для этого используют JavaScript.
Чтобы отправить запрос, нам понадобится встроенный объект XMLHttpRequest()
. Вот как мы вводим его в повествование:
// создаём новый экземпляр запроса XHR
let xhr = new XMLHttpRequest();
Для запроса нам нужно знать адрес, куда будем отправлять наш JSON — это и есть адрес нашего скрипта, который мы напишем позже. Мы будем писать его на PHP, поэтому заранее можем придумать ему имя и адрес, где он будет лежать: http://mihailmaximov.ru/projects/json/json.php.
// адрес, куда мы отправим нашу JSON-строку
url = "http://mihailmaximov.ru/projects/json/json.php";
Когда мы знаем адрес, мы можем открыть соединение, чтобы сервер был готов принять наши данные. Это значит, что мы пока ничего ценного туда не посылаем, а просто предупреждаем сервер, что скоро что-то прилетит:
// открываем соединение. url — это переменная с нашим адресом
xhr.open("POST", url, true);
Теперь напишем заголовок запроса, чтобы сервер понимал, какие данные мы ему пришлём и как ему их обрабатывать. Так как у нас JSON, то это и пропишем в заголовке:
// устанавливаем заголовок —
выбираем тип контента, который отправится на сервер,
в нашем случае мы явно пишем, что это JSON
setRequestHeader("Content-Type", "application/json");
Чуть ниже сразу пропишем поведение скрипта на случай ответа сервера. Сервер должен обработать наши данные, вернуть ответ, а мы должны этот ответ поймать и вывести на страницу:
// когда придёт ответ на наше обращение к серверу, мы его обработаем здесь
xhr.onreadystatechange = function () {
// если запрос принят и сервер ответил, что всё в порядке
if (xhr.readyState === 4 && xhr.status === 200) {
// выводим то, что ответил нам сервер — так мы убедимся, что данные он получил правильно
result.innerHTML = this.responseText;
}
};
Последнее, что нам осталось сделать, — вытащить наши введённые данные из полей, собрать из них JSON и отправить на сервер:
// преобразуем наши данные JSON в строку
var data = JSON.stringify({ "name":
name.value, "lastname": lastname.value });
// когда всё готово, отправляем JSON на сервер
xhr.send(data);
<!-- скрипт, который обработает нажатие на кнопку и отправит данные на сервер -->
<script>
// эта функция сработает при нажатии на кнопку
function sendJSON() {
// с помощью jQuery обращаемся к элементам на странице по их именам
let name = document.querySelector('#name');
let lastname = document.querySelector('#lastname');
// а вот сюда мы поместим ответ от сервера
let result = document.querySelector('.result');
// создаём новый экземпляр запроса XHR
let xhr = new XMLHttpRequest();
// адрес, куда мы отправим нашу JSON-строку
let url = "http://mihailmaximov.ru/projects/json/json.php";
// открываем соединение
xhr.open("POST", url, true);
// устанавливаем заголовок — выбираем тип контента, который отправится на сервер, в нашем случае мы явно пишем, что это JSON
xhr.setRequestHeader("Content-Type", "application/json");
// когда придёт ответ на наше обращение к серверу, мы его обработаем здесь
xhr.onreadystatechange = function () {
// если запрос принят и сервер ответил, что всё в порядке
if (xhr.readyState === 4 && xhr.status === 200) {
// выводим то, что ответил нам сервер — так мы убедимся, что данные он получил правильно
result.innerHTML = this.responseText;
}
};
// преобразуем наши данные JSON в строку
var data = JSON.stringify({ "name": name.value, "lastname": lastname.value });
// когда всё готово, отправляем JSON на сервер
xhr.send(data);
}
</script>
Пишем PHP-скрипт для сервера
Задача скрипта пока будет очень простой — ему нужно будет получить наши данные и показать, что всё пришло как нужно. В PHP уже встроена команда, которая разбирает JSON-строку на составляющие, поэтому весь скрипт будет занимать три строчки:
<?php
// на какие данные рассчитан этот скрипт
header("Content-Type: application/json");
// разбираем JSON-строку на составляющие встроенной командой
$data = json_decode(file_get_contents("php://input"));
// отправляем в ответ строку с подтверждением
echo "Сервер получил следующие данные: имя — $data->name, фамилия — $data->lastname";
Для получения данных наш PHP-скрипт использует стандартную команду file_get_contents("php://input")
. Она просто ждёт, когда что-то прилетит, и отправляет результат в выбранную переменную. Дальше её можно разобрать как JSON-объект командой json_decode()
и работать с данными напрямую.
Последняя команда echo
отправляет в ответ то, что написано в двойных кавычках. Там мы обращаемся к переменной $data, где хранятся присланные данные. Именно этот ответ будет обрабатывать скрипт на JavaScript, в функции xhr.onreadystatechange, которую мы прописали раньше.
Сам код нам нужно сохранить как json.php и положить в папку /projects/json/ на нашем сайте — так мы прописали в скрипте на JavaScript.
Настраиваем сервер
Если мы сейчас попробуем нажать на кнопку, браузер нам выдаст ошибку:
Штука в том, что если сервер заранее всем не сообщит, что он готов работать с запросами, то браузер не даст нашей локальной странице на компьютере получить данные с другого сервера в интернете. Это сделано в целях безопасности, например, чтобы при оплате картой данные не ушли на другой сервер кроме нужного.
Чтобы браузер разрешил нам получать и отправлять данные с сервера, нам нужно настроить сервер. Настройка происходит в файле .htaccess: это такой системный файл, который лежит на вашем сервере и подсказывает серверу, как себя вести в разных ситуациях, что-то вроде инструкции. Название .htaccess неслучайно: у файла как бы нет имени, но есть расширение .htaccess, и в обычных папках этот файл не будет виден.
Создаём пустой файл, пишем в него вот такое колдовство и сохраняем как .htaccess
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"
Header add Access-Control-Allow-Headers
"origin, x-requested-with, content-type"
Первая строка разрешает серверу работать с запросами от любых страниц (хоть это и небезопасно, но пока мы учимся — так можно). Вторая строка содержит список разрешённых запросов. Третья разрешает нужные нам заголовки в запросе.
Фактически этот файл сейчас означает: «разрешаю тебе принимать запросы со всех сайтов, вот такого типа запросы можно принимать, вот такие у них могут быть заголовки». В буквальном смысле методичка.
Откуда вы знаете, что нужны именно эти команды?
Когда мы писали эту статью, нам потребовалось почитать справочники и форумы, протестировать несколько вариантов команд и в итоге найти именно эту — ту, что работает.
Вся информация по командам и настройке в интернете уже есть. Нужно просто ее искать, анализировать и тестировать.
Теперь в интернете есть ещё и эта статья, которая поможет вам меньше искать :-)
Файл .htaccess нужно не потерять (на некоторых операционках он станет невидимым, как только вы его сохраните как .htaccess — придётся покопаться в настройках, чтобы его раскрыть). Загружаем его на сервер.
Перезапускаем нашу локальную страничку и пробуем её в действии.
Что дальше
Мы научились отправлять данные на сервер и немного работать там с ними. Дальше попробуем заменить в наших проектах локальное хранение данных на хранение на сервере, чтобы проекты работали с любого браузера.