Александр Меняйло

Александр Меняйло

Разработчик. Учёный

©2021

Wix.com как бесплатный backend для вашего приложения

Однажды мне захотелось сделать небольшое, но, как мне кажется, полезное веб приложение Ethereum events. Я его сделал, но встал вопрос о том, как поделиться им с другими людьми да и самому удобно пользоваться, т.е. нужен был хостинг веб сайта. Конечно, когда ты создаёшь большой проект, то вопрос где размещать свой сайт не стоит: вы скорей всего купите какой-нибудь VPS. Но для относительно простого сайта тратить деньги на хостинг обычно нет никакого желания.

Я совершенно новичок в веб разработке и недавно открыл для себя GitHub Pages. Оказалось, что это очень удобная бесплатная платформа для хостинга своих статических веб страниц. Там нет рекламы, очень удобное развёртывание, есть SSL, бесплатно можно подключить свой домен, никаких сторонних скриптов, никаких “конструкторов сайтов”, весь код принадлежит тебе. Идеально для тех, кто пишет свой сайт с нуля. В общем очень круто, я был в восторге.

Но минус, конечно, в том, что нельзя ничего исполнять на сервере. Т.е. GitHub Pages - это чисто статика. А что делать, если нужно обработать информацию на сервере? Вариантов, когда может потребоваться сервер для статического сайта масса: вести базу данных, делать “секретные” вычисления, иметь обратную связь без привязки к социальным сетям и др. Ну, например, на своём сайте я хотел иметь возможность обратной связи: когда человек оставляет мне сообщение, оно отправляется мне на сервер, сохраняется в базу данных для анализа и дублируется ко мне в телеграм.

Значит задача: обзавестись веб сервером. Но опять таки, для простых сайтов не хочется платить за это деньги. И вот тут я открыл для себя Wix.com.

Да, это один из многих бесплатных конструктор сайтов, который имеет в себе кучу разных шаблонов для их создания. В бесплатном плане на созданный вами сайт ставится реклама, даётся адрес вида https://<ваш логин на Wix>.wixsite.com/<название вашего сайта>/. Подключить свой домен стоит денег. Контроля над конечным кодом нет. Это всё совершенно не подходит для моих целей. Но есть одно но: Wix.com позволяет писать серверные скрипты! И причём не брать за это денег. И теперь уже не важен какой адрес вашего сайта на Wix, т.к. теперь это не сайт, а сервер и руками его адрес вводить никто не будет.

Программируется это всё на JavaScript с использованием специального API, которое называется Corvid. API предоставляет функции для работы со встроенной в Wix базой данных, а также для отправки запросов и ответов сервера и т.д.

Для формирования произвольных ответов на запросы к серверу в редакторе вашего сайта Wix в папке “Backend” нужно создать специальный файл с именем “http-fuctions.js”. Corvid предоставляет разные функции для работы с запросами. Например, для обработки GET запросов в файле “http-fuctions.js” нужно создать функцию get_<ваше_имя_для_get_функции>. В параметрах передаётся объект запроса. Эта функция будет вызываться при GET запросе на следующий адрес: https://<ваш логин на Wix>.wixsite.com/<название вашего сайта>/_functions/<ваше_имя_для_get_функции>.

Аналогичные функции присутствуют для POST, OPTIONS и других видов запросов.

Для ответа сервера можно использовать одну из встроенных в Corvid функций, например ok(), которая отсылает статус 200. В параметрах можно формировать нужные заголовки ответа. Универсальной функцией для ответа является response(), где в параметрах можно передать не только заголовки ответа, но и статус ответа.

Как видите, ничего сложного. Но есть нюансы. Например, какой бы в заголовки ответа не ставить Content-Type, всё равно Wix сервер отсылает application/json.

Также есть особенности для POST запросов со сторонних не Wix адресов (наш случай). Когда браузер делает запрос на адрес отличный от того, с которого была загружена страница, то в дело вступает CORS. Если кратко, то браузер сначала отсылает на сервер запрос типа OPTIONS и ожидает от сервера ответа с заголовком Access-Control-Allow-Origin, со значением равным адресу нашего статического веб сайта. И уже потом, если адрес совпадёт, то отсылается желаемый POST запрос. Т.е. браузер должен убедиться, что сервер явно разрешает к себе запросы с конкретных сторонних адресов.

Предварительный OPTIONS запрос посылается браузером только если желаемый POST запрос содержит заголовок Content-Type отличный от application/x-www-form-urlencoded, multipart/form-data или text/plain. Например для POST запроса с Content-Type: application/json браузер сформирует предварительный OPTIONS запрос. Проблема в том, что Wix отвечает на такие OPTIONS запросы статусом 403 Forbidden, даже если подготовить специальную функцию options_<имя_функции>. Выход только один: посылать данные на Wix сервер с заголовком Content-Type: text/plain, даже если это JSON. В ответ сервера всё равно нужно поставить Access-Control-Allow-Origin, иначе в JS нашего сайта, откуда был отправлен запрос, возникнет исключение.

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

Для начала нужно создать телеграм бота, который будет отсылать вам сообщения с сайта. Для этого нужно просто воспользоваться ботом @BotFather. При запросе к этому боту высылается подробная информация что и как делать. Придумываете имя для бота и имя пользователя. В ответ @BotFather вышлет token, благодаря которому можно отсылать сообщения от имени вашего бота. Отправка сообщений осуществляется через HTTP запросы, куда включается token вашего бота.

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

const msg = 
    {
        text: text,
        name: name,
    };
fetch('https://<ваш логин на Wix>.wixsite.com/<название вашего сайта>/_functions/msg',
    {
        method: 'POST',
        headers:
        {
            'Content-Type': 'text/plain' //'application/json' не работает
        },
        body: JSON.stringify(msg)
    }).then((res) =>
        {
            if (!res.ok) alert('Ошибка доставки сообщения.');
        }).catch((err) =>
            {
                alert('Ошибка доставки сообщения: ' + err);
            });

Ниже приведён код серверной части на Wix. Этот код должен находится в файле “http-fuctions.js”.

import {serverError, response, forbidden} from 'wix-http-functions';
import fetch from 'wix-fetch';
import wixData from "wix-data";

const ALLOWED_ORIGIN = 'https://<Ваш_статический_сайт>';

export function post_msg(req)
{
    if (req.headers.origin === ALLOWED_ORIGIN) //Проверка заголовка ORIGIN, чтобы убедиться, что запрос пришёл с ожидаемого сайта.
    {
        return req.body.json().then((data) => //Сохраняем данные в базу данных wix.
        {
            return wixData.insert('<имя_базы_данных_в_Wix>', data);
        }).then((data) => //Отправляем сообщение в телеграм
        {
            const msg = 
            {
                chat_id: <chat_id_вашего_телеграм>,
                text: 'Name: ' + data.name + '\n' + data.text
            };
            return fetch('https://api.telegram.org/bot<token_вашего_бота>/sendMessage',
            {
                method: 'POST',
                headers:
                {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(msg)
            });
        }).then((res) => //Получаем ответ от сервера телеграм.
        {
            return res.json(); //Получаем из этого ответа JSON.
        }).then((tRes) =>
        {
            if(tRes.ok) //Если всё в порядке, сообщение в телеграм отправлено, то отправляем status 204 и CORS заголовок.
            {
                return response(
                {
                    status: 204,
                    headers: {'Access-Control-Allow-Origin': ALLOWED_ORIGIN}
                });
            }
            else
            {
                return response(
                {
                    status: 522
                });
            }
        }).catch((err) =>
        {
            return serverError();
        });
    }
    else
    {
        return forbidden();
    }
}

Здесь создана функция post_msg, в которую передаётся объект запроса от нашего статического сайта. wixData.insert - функция, которая вставляет полученное сообщение в заранее подготовленную таблицу базы данных Wix. Поля этой таблицы должны соответствовать свойствам JSON объекта, который мы передали в запросе.

Сообщение для телеграм формируется в объекте msg. Здесь свойство chat_id - это номер вашего телеграма, чтобы созданный вами бот знал кому отправлять сообщение. Узнать ваш chat_id можно у бота @userinfobot.

Теперь все сообщения с вашего статического сайта, размещённого, например, на GitHub Pages будут сохранятся в базе данных Wix и дублироваться к вам в телеграм.

Кроме того, конструктор Wix позволяет в пару кликов разместить на вашем Wix сайте таблицу, содержащую список всех сообщений, добавить сортировку и другие плюшки. Сделать на странице авторизацию, чтобы никто кроме вас эту таблицу не видел. В общем удобно и бесплатно. Надеюсь мой опыт будет кому-то полезен.