Перейти к основному содержимому

Ссылка (URL)

Поле типа Ссылка предназначено для хранения URL-адресов с автоматической валидацией и форматированием.

Основные характеристики

  • Тип данных: Строка с валидацией URL
  • Формат хранения: Полный URL с протоколом
  • Автоматическая валидация: Проверка корректности URL
  • Автодополнение протокола: Добавление https:// если не указан
  • Максимальная длина: До 2048 символов

Настройки поля

При создании поля типа "Ссылка" доступны следующие настройки:

  • Название поля: Отображаемое имя поля
  • Системное имя: Уникальный идентификатор для API
  • Описание: Подсказка для пользователей
  • Обязательное поле: Требовать заполнения
  • Протокол по умолчанию: https:// или http://
  • Разрешенные протоколы: http, https, ftp, mailto и др.
  • Открывать в новой вкладке: Настройка для отображения

Примеры использования

Веб-сайт компании

{
"name": "website",
"type": "url",
"defaultProtocol": "https"
}

Ссылка на профиль

{
"name": "linkedin_url",
"type": "url",
"placeholder": "https://linkedin.com/in/username"
}

Репозиторий GitHub

{
"name": "github_repo",
"type": "url",
"pattern": "^https://github\\.com/.+/.+$"
}

Документация

{
"name": "documentation_url",
"type": "url",
"required": false
}

Работа через API

Создание записи

const record = await emd.database.collection('companies').create({
name: 'Acme Corp',
website: 'https://example.com'
});

// Автодополнение протокола
const record = await emd.database.collection('companies').create({
name: 'Acme Corp',
website: 'example.com' // Сохранится как https://example.com
});

Получение URL

const record = await emd.database.collection('companies').get(recordId);

console.log(record.website);
// {
// href: "https://example.com/path?query=value",
// protocol: "https:",
// hostname: "example.com",
// pathname: "/path",
// search: "?query=value",
// hash: "",
// origin: "https://example.com"
// }

Поиск по URL

// Точное совпадение
const companies = await emd.database.collection('companies').find({
website: 'https://example.com'
});

// Поиск по домену
const companies = await emd.database.collection('companies').find({
'website.hostname': 'example.com'
});

// Поиск по части URL
const companies = await emd.database.collection('companies').find({
website: { $contains: 'example' }
});

Обновление URL

await emd.database.collection('companies').update(recordId, {
website: 'https://new-domain.com'
});

Валидация

Автоматическая валидация формата

try {
await emd.database.collection('companies').create({
name: 'Acme',
website: 'not-a-valid-url'
});
} catch (error) {
console.error(error.message); // "Invalid URL"
}

Проверка протокола

{
"name": "secure_url",
"type": "url",
"allowedProtocols": ["https"]
}
try {
await emd.database.collection('resources').create({
secure_url: 'http://example.com' // Только https разрешен
});
} catch (error) {
console.error(error.message); // "Only HTTPS protocol is allowed"
}

Проверка домена

{
"name": "github_url",
"type": "url",
"allowedDomains": ["github.com", "gitlab.com"]
}

Извлечение частей URL

const record = await emd.database.collection('companies').get(recordId);
const url = record.website;

console.log(url.href); // "https://example.com:8080/path?query=value#hash"
console.log(url.protocol); // "https:"
console.log(url.hostname); // "example.com"
console.log(url.port); // "8080"
console.log(url.pathname); // "/path"
console.log(url.search); // "?query=value"
console.log(url.hash); // "#hash"
console.log(url.origin); // "https://example.com:8080"

Отображение в интерфейсе

Кликабельная ссылка

const record = await emd.database.collection('companies').get(recordId);

// HTML
const link = `<a href="${record.website.href}" target="_blank" rel="noopener noreferrer">
${record.website.hostname}
</a>`;

Отображение с иконкой

const displayUrl = (url) => `
<a href="${url.href}" target="_blank" class="url-link">
<svg><!-- external link icon --></svg>
${url.hostname}
</a>
`;

Favicon

const record = await emd.database.collection('companies').get(recordId);
const faviconUrl = `https://www.google.com/s2/favicons?domain=${record.website.hostname}`;

// Или
const faviconUrl = `${record.website.origin}/favicon.ico`;

Типичные сценарии использования

Социальные сети

{
"name": "social_links",
"type": "json",
"default": {
"facebook": "",
"twitter": "",
"linkedin": "",
"instagram": ""
}
}

Или отдельные поля:

[
{
"name": "facebook_url",
"type": "url",
"pattern": "^https://(www\\.)?facebook\\.com/.+$"
},
{
"name": "twitter_url",
"type": "url",
"pattern": "^https://(www\\.)?twitter\\.com/.+$"
}
]

Внешние ресурсы

const record = await emd.database.collection('articles').create({
title: 'Статья',
source_url: 'https://example.com/article',
author_profile: 'https://example.com/author/john'
});

API endpoints

const record = await emd.database.collection('integrations').create({
name: 'External API',
endpoint: 'https://api.example.com/v1',
documentation: 'https://docs.example.com'
});

Операторы для URL полей

  • $eq — равно
  • $ne — не равно
  • $contains — содержит подстроку
  • $startsWith — начинается с
  • $in — входит в список
  • $exists — проверка наличия значения

Примеры запросов

Найти все HTTPS ссылки

const records = await emd.database.collection('resources').find({
'url.protocol': 'https:'
});

Найти ссылки на определенный домен

const records = await emd.database.collection('resources').find({
'url.hostname': 'github.com'
});

Найти ссылки с определенным путем

const records = await emd.database.collection('resources').find({
'url.pathname': { $startsWith: '/api/' }
});

Проверка доступности URL

Проверка статуса

async function checkUrlStatus(url) {
try {
const response = await fetch(url, { method: 'HEAD' });
return {
available: response.ok,
status: response.status
};
} catch (error) {
return {
available: false,
error: error.message
};
}
}

const record = await emd.database.collection('resources').get(recordId);
const status = await checkUrlStatus(record.url.href);

if (!status.available) {
await emd.database.collection('resources').update(recordId, {
url_status: 'broken',
last_checked: new Date()
});
}

Сокращение URL

Интеграция с сервисом сокращения

async function shortenUrl(longUrl) {
const response = await fetch('https://api.short.io/links', {
method: 'POST',
headers: {
'Authorization': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
originalURL: longUrl,
domain: 'short.io'
})
});

const data = await response.json();
return data.shortURL;
}

const record = await emd.database.collection('links').create({
original_url: 'https://example.com/very/long/url',
short_url: await shortenUrl('https://example.com/very/long/url')
});

QR-код для URL

const record = await emd.database.collection('resources').get(recordId);

// Генерация QR-кода
const qrCodeUrl = `https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=${encodeURIComponent(record.url.href)}`;

Предпросмотр ссылки (Open Graph)

async function getUrlPreview(url) {
const response = await fetch(`https://api.linkpreview.net/?q=${url}`);
const data = await response.json();

return {
title: data.title,
description: data.description,
image: data.image,
domain: data.url
};
}

const record = await emd.database.collection('bookmarks').get(recordId);
const preview = await getUrlPreview(record.url.href);

await emd.database.collection('bookmarks').update(recordId, {
preview_title: preview.title,
preview_description: preview.description,
preview_image: preview.image
});

Рекомендации

  • Всегда используйте HTTPS по умолчанию
  • Валидируйте URL на клиенте и сервере
  • Проверяйте доступность важных ссылок периодически
  • Используйте target="_blank" и rel="noopener noreferrer" для внешних ссылок
  • Отображайте только домен или короткую версию URL в списках
  • Добавляйте favicon для визуального распознавания
  • Храните метаданные (title, description) для предпросмотра
  • Используйте паттерны для валидации специфичных URL (GitHub, социальные сети)

Безопасность

Проверка на фишинг

const suspiciousDomains = [
'phishing-site.com',
'malware-site.com'
];

function isSafeUrl(url) {
return !suspiciousDomains.includes(url.hostname);
}

Санитизация URL

function sanitizeUrl(url) {
// Удалить javascript: и data: протоколы
if (url.protocol === 'javascript:' || url.protocol === 'data:') {
throw new Error('Unsafe URL protocol');
}
return url;
}

Отличие от других типов

  • URL vs String: URL обеспечивает валидацию и парсинг
  • URL vs Email: URL для веб-ссылок, Email для адресов почты
  • URL vs File: URL для внешних ресурсов, File для загруженных файлов