Ссылка (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 для загруженных файлов