arvancloud

ArvanCloud Edge Computing: уникальный опыт скорости и безопасности

С ArvanCloud Edge Computing вы можете запускать свои скрипты и обрабатывать код для ваших онлайн-сервисов в ближайшей точке к пользователю без необходимости сервера, обеспечивая новый уровень скорости и безопасности.

blur ArvanCloud Edge Computing: уникальный опыт скорости и безопасности
Бесплатный SSL-сертификат

Бесплатный SSL-сертификат

Все домены, добавленные на платформу Edge Computing, автоматически получают бесплатные SSL-сертификаты.

Быстрая и легкая настройка

Быстрая и легкая настройка

С помощью панели ArvanCloud или CLI запускайте и разворачивайте свои онлайн-сервисы менее чем за 30 секунд.

Оптимизированная производительность

Оптимизированная производительность

Весь ваш бизнес-код размещается на ArvanCloud CDN PoPs и выполняется из ближайшей точки к пользователю.

Высокая безопасность

Высокая безопасность

Наслаждайтесь передовыми функциями безопасности CDN от ArvanCloud для разработки ваших сервисов в безопасной и надежной среде.

Особенности

Развивайте свои услуги с помощью расширенных функций

Серверлесс решение

Вы можете разрабатывать свои онлайн-сервисы без необходимости облачного или виртуального сервера и запускать контент из ближайшей точки к пользователю.

Высокая масштабируемость

Используйте неограниченные ресурсы сети доставки контента без балансировки нагрузки сервера или распределяйте трафик между несколькими PoPs.

Развертывание одним кликом

С готовыми к использованию кодами и шаблонами вы можете развернуть свой сервис всего одним кликом и настроить функции в соответствии с вашими потребностями.

Экономичный

Развертывание приложений с ArvanCloud Edge Computing позволяет вам доставлять ваши сервисы пользователям по минимальной цене.

Отладка перед выпуском

Легко редактируйте и вылаживайте свои финальные версии с помощью Console Log перед запуском вашего сайта или приложения для публики.

Быстрые ответы

С ArvanCloud Edge Computing отвечайте на запросы пользователей из ближайшего местоположения и повышайте скорость доставки вашего сервиса.

Более 40

PoPs в высокотрафиковых регионах по всему миру

99.99%

Время безотказной работы и постоянная доступность сервиса

500 миллионов

Пропускная способность обработки запросов в час
Готовые шаблоны

Разрабатывайте функциональные сервисы всего одним кликом

Балансировщик нагрузки Round Robin

Защита от горячих ссылок

Основная аутентификация

SSR HTMX

Балансировщик нагрузки Round Robin

С балансировщиком нагрузки Round Robin ваши входящие запросы равномерно распределяются между несколькими серверами. Это обеспечивает сбалансированное распределение трафика и лучшую производительность, а также помогает вам оставаться доступным и стабильным в условиях высокой нагрузки.

Просмотр
Copied
                                            
'use strict';

// Upstream URLs
const UPSTREAM_URLS = [
    new URL("http://localhost:4000"),
    new URL("http://localhost:4001"),
    new URL("http://localhost:4002"),
    new URL("http://localhost:4003"),
];

let NEXT_UPSTREAM_INDEX = 0;
async function handleRequest(request) {
    let upstreamIdx = NEXT_UPSTREAM_INDEX;
    NEXT_UPSTREAM_INDEX = (NEXT_UPSTREAM_INDEX + 1) % UPSTREAM_URLS.length;
    let upstream = UPSTREAM_URLS[upstreamIdx];
    return await doRequest(request, upstream);
}
function doRequest(request, upstream) {
    let newUrl = new URL(request.url);
    newUrl.protocol = upstream.protocol;
    newUrl.host = upstream.host;
    let newReq = new Request(newUrl.toString(), request);
    return fetch(newReq);
}

addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event.request));
});
                                        
Защита от горячих ссылок

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

Просмотр
Copied
                                            
'use strict';

// Your domains that is allowed to access hotlinks
const DOMAINS = ["time.ir", "fa.wikipedia.org"];
// Upstream url
const UPSTREAM_URL = "http://localhost:4000";
// File extensions that hotlink is against
const EXTENSIONS = ["jpg", "jpeg", "png", "ico", "gif"];

async function handleRequest(request) {
    const fileExt = extractUrlFileExtension(request.url);
    if (fileExt == null || !EXTENSIONS_SET.has(fileExt)) {
        return await doRequest(request);
    }
    else {
        return await checkReferrerAndDoRequest(request);
    }
}
async function doRequest(request) {
    let newUrl = new URL(request.url);
    newUrl.protocol = UPSTREAM_PROTOCOL;
    newUrl.host = UPSTREAM_HOST;
    let newReq = new Request(newUrl.toString(), request);
    return fetch(newReq);
}
async function checkReferrerAndDoRequest(request) {
    let response;
    const referrerHeader = request.headers.get("referer");
    if (referrerHeader != null) {
        let domain = extractDomainFromReferrer(referrerHeader);
        if (domain == null || DOMAINS_SET.has(domain)) {
            response = await doRequest(request);
        }
        else {
            response = UNAUTHORIZED_RESPONSE;
        }
    }
    else {
        response = await doRequest(request);
    }
    return response;
}
function extractDomainFromReferrer(referrer) {
    try {
        return new URL(referrer).hostname;
    }
    catch (e) {
        return null;
    }
}
function extractUrlFileExtension(url) {
    try {
        let pathname = new URL(url).pathname;
        let lastDotIdx = pathname.lastIndexOf(".");
        if (lastDotIdx == -1) {
            return null;
        }
        else {
            return pathname.substring(1 + lastDotIdx);
        }
    }
    catch (e) {
        return null;
    }
}
const DOMAINS_SET = (() => {
    const set = new Set();
    DOMAINS.forEach((i) => set.add(i));
    return set;
})();
const EXTENSIONS_SET = (() => {
    const set = new Set();
    EXTENSIONS.forEach((i) => set.add(i));
    return set;
})();
const UNAUTHORIZED_RESPONSE = new Response(null, {
    status: 401,
});
const UPSTREAM_PROTOCOL = new URL(UPSTREAM_URL).protocol;
const UPSTREAM_HOST = new URL(UPSTREAM_URL).host;

addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event.request));
});
                                        
Основная аутентификация

Шаблон Basic Auth позволяет вам легко контролировать доступ к защищенным разделам вашего сайта с помощью простого имени пользователя и пароля. Этот скрипт быстро реализуется и отвечает базовым потребностям безопасности вашего сервиса.

Просмотр
Copied
                                            
'use strict';

// Credentials for users
const UserPassList = [{ user: "admin", pass: "adminpass" }];
// Upstream url
const UPSTREAM_URL = "http://localhost:4000";

async function handleRequest(request) {
    const authHeader = request.headers.get("Authorization");
    let response;
    if (authHeader != null && authHeader.startsWith("Basic")) {
        let encodedCredential = authHeader.substring(6);
        if (CREDENTIALS.has(encodedCredential)) {
            let newUrl = new URL(request.url);
            newUrl.protocol = UPSTREAM_PROTOCOL;
            newUrl.host = UPSTREAM_HOST;
            let newReq = new Request(newUrl.toString(), request);
            newReq.headers.delete("Authorization");
            response = await fetch(newReq);
        }
        else {
            response = UNAUTHORIZED_INVALID_CREDENTIALS_RESPONSE;
        }
    }
    else {
        response = UNAUTHORIZED_NEEDS_LOGIN_RESPONSE;
    }
    return response;
}
const UNAUTHORIZED_NEEDS_LOGIN_RESPONSE = new Response(null, {
    //TODO: Add realm and/or charset if needed
    headers: new Headers({
        "WWW-Authenticate": "Basic",
    }),
    status: 401,
});
const UNAUTHORIZED_INVALID_CREDENTIALS_RESPONSE = new Response(null, {
    status: 401,
});
// Key: Base64 encoded username:password
// Value: username
const CREDENTIALS = (() => {
    const map = new Map();
    for (let i of UserPassList) {
        // TODO: this may not properly work with utf8
        const encoded = btoa(`${i.user}:${i.pass}`);
        map.set(encoded, i.user);
    }
    return map;
})();
const UPSTREAM_PROTOCOL = new URL(UPSTREAM_URL).protocol;
const UPSTREAM_HOST = new URL(UPSTREAM_URL).host;

addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event.request));
});
                                        
SSR HTMX

С шаблоном Server-Side Rendering в HTMX вы можете динамически визуализировать веб-страницы с сервера и обновлять различные разделы без полной перезагрузки страницы. Это поможет улучшить скорость загрузки и пользовательский опыт.

Просмотр
Copied
                                            
'use strict';

const TODO_LIST = ["test"];
function createDb() {
    return {
        add: async (title) => {
            TODO_LIST.push(title);
        },
        list: async () => TODO_LIST,
    };
}
const DefaultDB = createDb();

var Index = "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <title>Todo list</title>\n  <script src=\"https://unpkg.com/htmx.org@1.9.5\"></script>\n  <link rel=\"stylesheet\" href=\"/styles.css\">\n</head>\n\n<body>\n  <div>\n    <div>\n      <h1>To-Do List</h1>\n    </div>\n    <form hx-post=\"/add\" hx-target=\"#list\" hx-swap=\"beforeend\">\n      <div>\n        <input type=\"text\" placeholder=\"Task title\" name=\"title\" required />\n        <button type=\"submit\">Add</button>\n      </div>\n    </form>\n    <div id=\"list\" hx-get=\"/list\" hx-trigger=\"load\"></div>\n  </div>\n</body>\n\n</html>";

var Styles = "h1 {\n  color: red;\n}\n";

async function handleRequest(request) {
    // simple router:
    let content = "";
    const url = new URL(request.url);
    switch (url.pathname) {
        case "/":
            content = Index;
            break;
        case "/styles.css":
            return new Response(Styles, {
                headers: { "Content-Type": "text/css" },
            });
        case "/add":
            const data = await request.formData();
            const title = data.get("title").toString();
            await DefaultDB.add(title);
            content = `<li>${title}</li>`;
            break;
        case "/list":
            content = (await DefaultDB.list()).map((x) => `<li>${x}</li>`).join("");
            break;
        default:
            content = "Not found :(";
    }
    if (request.url)
        return new Response(content, {
            headers: { "Content-Type": "text/html; charset=utf-8" },
        });
}

addEventListener("fetch", (event) => {
    event.respondWith(handleRequest(event.request));
});
                                        
Цены

Доступная инфраструктура для онлайн-бизнеса

Оплата по мере использования

Бесплатный входящий трафик
100 приложений Edge Computing
100,000 бесплатных запросов в месяц
Начать бесплатно

Корпоративный

Бесплатный входящий трафик
500 приложений Edge Computing
Неограниченные запросы
Оставить заявку
Итоговая стоимость ArvanCloud Edge Computing рассчитывается на основе вашего использования различных функций. Узнайте больше подробностей на странице ценообразования.
Ценообразование Edge Computing

Скорость и безопасность с ArvanCloud Edge Computing

Разрабатывайте свои сервисы без необходимости множественных облачных инфраструктур.