Edge Computing: Uma Experiência Única de Velocidade e Segurança
Todos os domínios adicionados à plataforma Edge Computing recebem automaticamente certificados SSL gratuitos.
Com o painel do Arvancloud ou CLI, você pode lançar e implantar os serviços online do seu negócio em menos de 30 segundos.
Todo o código da sua empresa é hospedado nos PoPs do CDN da Arvancloud e executado a partir do ponto mais próximo ao usuário.
Aproveite os recursos avançados de segurança do CDN da Arvancloud para desenvolver seus serviços em um ambiente seguro e confiável.
Desenvolva Seus Serviços Online com Recursos Avançados
Solução Serverless
Desenvolva seus serviços online sem a necessidade de servidores físicos ou virtuais, e execute o conteúdo a partir do ponto mais próximo ao usuário.
Alta Escalabilidade
Utilize os recursos ilimitados da rede de entrega de conteúdo sem precisar de balanceamento de carga nos servidores ou distribuição de tráfego em múltiplos PoPs.
Implantação com Um Clique
Com códigos e modelos prontos para uso, implante seu serviço com apenas um clique e personalize os recursos conforme suas necessidades.
Custo-Benefício
Implantar aplicações com o Arvancloud Edge Computing permite entregar seus serviços aos usuários com o menor custo possível.
Debug Antes do Lançamento
Edite e depure facilmente as versões finais usando o Console Log antes de lançar seu site ou aplicativo ao público.
Respostas Rápidas
Com o Arvancloud Edge Computing, responda às solicitações dos usuários a partir da localização mais próxima, aumentando a velocidade de entrega dos seus serviços.
Mais de 40
99.99%
500 milhões
Desenvolva serviços funcionais com apenas um clique.
Balanceador de Carga Round Robin
Proteção contra Hotlink
Autenticação Básica
SSR HTMX
Com o Balanceador de Carga Round Robin, suas solicitações recebidas são distribuídas uniformemente entre múltiplos servidores. Isso oferece uma distribuição equilibrada de tráfego, melhor desempenho e maior estabilidade em condições de alto tráfego.
Visualizar
'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));
});
Ativando a Proteção contra Hotlink, você impede que imagens, vídeos e outros conteúdos do seu site sejam utilizados de forma indevida em outros sites. Isso reduz o consumo de banda e os custos, além de melhorar a segurança e proteger seu conteúdo.
Visualizar
'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));
});
O modelo de Autenticação Básica permite controlar facilmente o acesso a seções protegidas do seu site com um simples nome de usuário e senha. Este script é rápido de implementar e atende às necessidades básicas de segurança do seu serviço.
Visualizar
'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));
});
Com o modelo de Renderização no Servidor (SSR) em HTMX, você pode renderizar páginas web dinamicamente a partir do servidor e atualizar seções específicas sem recarregar toda a página. Isso ajuda a melhorar a velocidade de carregamento e a experiência do usuário.
Visualizar
'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));
});