Walidacja Rekordów MX: Przewodnik dla Deweloperów

Leo
LeoFounder, BillionVerify

Dowiedz się, jak zaimplementować walidację rekordów MX. Przewodnik obejmujący wyszukiwanie DNS, parsowanie rekordów MX, obsługę priorytetów i praktyki.

Cover Image for Walidacja Rekordów MX: Przewodnik dla Deweloperów

Każdy wysyłany e-mail podróżuje przez starannie zorkiestrowaną sieć serwerów, a rekordy Mail Exchange (MX) są drogowskazami kierującymi tą podróżą. Zrozumienie, jak walidować rekordy MX, to fundamentalna umiejętność dla każdego dewelopera budującego systemy weryfikacji e-mail, formularze kontaktowe lub aplikacje zbierające adresy e-mail. Ten kompleksowy przewodnik bada walidację rekordów MX od podstawowych koncepcji po zaawansowane strategie implementacji, dając ci wiedzę potrzebną do zbudowania solidnej weryfikacji e-mail w swoich aplikacjach.

Zrozumienie rekordów MX

Rekordy Mail Exchange to rekordy DNS określające, które serwery poczty są odpowiedzialne za przyjmowanie wiadomości e-mail w imieniu domeny. Kiedy wysyłasz e-mail na adres user@example.com, twój serwer poczty musi wiedzieć, gdzie go dostarczyć. Rekordy MX dostarczają tę informację, wskazując na serwery poczty domeny.

Jak działają rekordy MX

Kiedy e-mail jest wysyłany, wysyłający serwer poczty wykonuje wyszukiwanie DNS, aby znaleźć rekordy MX dla domeny odbiorcy. To wyszukiwanie zwraca jedną lub więcej nazw hostów serwerów poczty wraz z wartościami priorytetów wskazującymi kolejność preferencji.

Typowe wyszukiwanie rekordu MX dla gmail.com może zwrócić:

gmail.com.    MX    5     gmail-smtp-in.l.google.com.
gmail.com.    MX    10    alt1.gmail-smtp-in.l.google.com.
gmail.com.    MX    20    alt2.gmail-smtp-in.l.google.com.
gmail.com.    MX    30    alt3.gmail-smtp-in.l.google.com.
gmail.com.    MX    40    alt4.gmail-smtp-in.l.google.com.

Serwer wysyłający najpierw próbuje dostarczyć do serwera o najniższym priorytecie (w tym przypadku priorytet 5). Jeśli ten serwer jest niedostępny, próbuje następnego poziomu priorytetu i tak dalej. Ta redundancja zapewnia dostarczenie e-maila nawet wtedy, gdy pojedyncze serwery są wyłączone.

Komponenty rekordów MX

Każdy rekord MX zawiera dwie podstawowe informacje:

Priorytet (Preferencja)

Wartość liczbowa wskazująca kolejność, w jakiej należy wypróbować serwery poczty. Niższe liczby oznaczają wyższy priorytet. Serwery o tym samym priorytecie są próbowane w losowej kolejności, zapewniając równoważenie obciążenia.

Nazwa hosta serwera poczty

Pełna kwalifikowana nazwa domeny (FQDN) serwera poczty obsługującego e-mail dla domeny. Ta nazwa hosta musi być rozwiązywana na adres IP za pomocą rekordu A lub AAAA.

Dlaczego rekordy MX są ważne dla weryfikacji e-mail

Walidacja rekordów MX służy jako krytyczny punkt kontrolny w procesie weryfikacji e-mail:

Potwierdzenie istnienia domeny

Jeśli domena nie ma rekordów MX, zazwyczaj nie może odbierać poczty e-mail. Niektóre domeny mogą mieć fallback na rekord A, ale brak rekordów MX często jest silnym wskaźnikiem, że domena nie jest skonfigurowana do obsługi poczty e-mail.

Weryfikacja infrastruktury

Prawidłowe rekordy MX, które rozwiązują się na działające serwery poczty, wskazują, że domena ma infrastrukturę pocztową. To nie gwarantuje, że konkretny adres istnieje, ale potwierdza, że domena może odbierać e-mail.

Wykrywanie spamu i oszustw

Legalne firmy utrzymują właściwe rekordy MX. Podejrzane domeny używane do spamu lub oszustw często mają nieprawidłowo skonfigurowane lub brakujące rekordy MX.

Optymalizacja wydajności

Sprawdzanie rekordów MX przed próbą weryfikacji SMTP pozwala uniknąć marnowania czasu na łączenie się z domenami, które nie mogą odbierać poczty e-mail.

Implementacja wyszukiwania rekordów MX

Przyjrzyjmy się, jak zaimplementować walidację rekordów MX w różnych środowiskach programistycznych.

Implementacja w Node.js

Node.js zapewnia wbudowaną rozdzielczość DNS za pomocą modułu dns:

const dns = require('dns').promises;

async function getMxRecords(domain) {
  try {
    const records = await dns.resolveMx(domain);

    // Sortuj według priorytetu (najniższy jako pierwszy)
    records.sort((a, b) => a.priority - b.priority);

    return {
      success: true,
      domain,
      records: records.map(r => ({
        exchange: r.exchange,
        priority: r.priority
      }))
    };
  } catch (error) {
    return {
      success: false,
      domain,
      error: error.code,
      message: getMxErrorMessage(error.code)
    };
  }
}

function getMxErrorMessage(code) {
  const messages = {
    'ENODATA': 'Nie znaleziono rekordów MX dla tej domeny',
    'ENOTFOUND': 'Domena nie istnieje',
    'ETIMEOUT': 'Przekroczono limit czasu wyszukiwania DNS',
    'ESERVFAIL': 'Serwer DNS nie odpowiedział'
  };
  return messages[code] || 'Nieznany błąd DNS';
}

// Użycie
const result = await getMxRecords('gmail.com');
console.log(result);

Implementacja w Pythonie

Moduł dns.resolver Pythona z biblioteki dnspython zapewnia kompleksowe możliwości wyszukiwania DNS:

import dns.resolver
import dns.exception

def get_mx_records(domain):
    try:
        answers = dns.resolver.resolve(domain, 'MX')

        records = []
        for rdata in answers:
            records.append({
                'exchange': str(rdata.exchange).rstrip('.'),
                'priority': rdata.preference
            })

        # Sortuj według priorytetu
        records.sort(key=lambda x: x['priority'])

        return {
            'success': True,
            'domain': domain,
            'records': records
        }

    except dns.resolver.NXDOMAIN:
        return {
            'success': False,
            'domain': domain,
            'error': 'NXDOMAIN',
            'message': 'Domena nie istnieje'
        }

    except dns.resolver.NoAnswer:
        return {
            'success': False,
            'domain': domain,
            'error': 'NoAnswer',
            'message': 'Nie znaleziono rekordów MX dla tej domeny'
        }

    except dns.exception.Timeout:
        return {
            'success': False,
            'domain': domain,
            'error': 'Timeout',
            'message': 'Przekroczono limit czasu wyszukiwania DNS'
        }

# Użycie
result = get_mx_records('gmail.com')
print(result)

Implementacja w Go

Pakiet net Go zapewnia proste funkcje wyszukiwania DNS:

package main

import (
    "fmt"
    "net"
    "sort"
)

type MxResult struct {
    Success bool
    Domain  string
    Records []MxRecord
    Error   string
}

type MxRecord struct {
    Exchange string
    Priority uint16
}

func getMxRecords(domain string) MxResult {
    records, err := net.LookupMX(domain)

    if err != nil {
        return MxResult{
            Success: false,
            Domain:  domain,
            Error:   err.Error(),
        }
    }

    if len(records) == 0 {
        return MxResult{
            Success: false,
            Domain:  domain,
            Error:   "Nie znaleziono rekordów MX",
        }
    }

    // Sortuj według priorytetu
    sort.Slice(records, func(i, j int) bool {
        return records[i].Pref < records[j].Pref
    })

    result := MxResult{
        Success: true,
        Domain:  domain,
        Records: make([]MxRecord, len(records)),
    }

    for i, r := range records {
        result.Records[i] = MxRecord{
            Exchange: r.Host,
            Priority: r.Pref,
        }
    }

    return result
}

func main() {
    result := getMxRecords("gmail.com")
    fmt.Printf("%+v\n", result)
}

Zaawansowane techniki walidacji MX

Podstawowe wyszukiwanie MX potwierdza, że rekordy istnieją, ale kompleksowa walidacja e-mail wymaga głębszej analizy.

Walidacja łączności z serwerem poczty

Rekordy MX wskazują na nazwy hostów, które muszą być rozwiązywane na adresy IP. Sprawdź, czy serwery poczty są faktycznie dostępne:

const dns = require('dns').promises;
const net = require('net');

async function validateMxConnectivity(domain) {
  // Pobierz rekordy MX
  const mxResult = await getMxRecords(domain);

  if (!mxResult.success) {
    return mxResult;
  }

  // Waliduj każdy serwer poczty
  const validatedRecords = [];

  for (const record of mxResult.records) {
    const validation = await validateMailServer(record.exchange);
    validatedRecords.push({
      ...record,
      ...validation
    });
  }

  return {
    success: true,
    domain,
    records: validatedRecords,
    hasReachableServer: validatedRecords.some(r => r.reachable)
  };
}

async function validateMailServer(hostname) {
  try {
    // Rozwiąż nazwę hosta na IP
    const addresses = await dns.resolve4(hostname);

    if (addresses.length === 0) {
      return { reachable: false, error: 'Brak rekordu A' };
    }

    // Testuj połączenie z portem 25
    const connected = await testConnection(addresses[0], 25);

    return {
      reachable: connected,
      ip: addresses[0],
      error: connected ? null : 'Połączenie odrzucone'
    };
  } catch (error) {
    return {
      reachable: false,
      error: error.message
    };
  }
}

function testConnection(host, port, timeout = 5000) {
  return new Promise((resolve) => {
    const socket = new net.Socket();

    socket.setTimeout(timeout);

    socket.on('connect', () => {
      socket.destroy();
      resolve(true);
    });

    socket.on('timeout', () => {
      socket.destroy();
      resolve(false);
    });

    socket.on('error', () => {
      resolve(false);
    });

    socket.connect(port, host);
  });
}

Obsługa fallbacku na rekord A

Kiedy nie istnieją rekordy MX, standardy e-mail (RFC 5321) określają, że należy użyć rekordu A domeny jako fallbacku. Zaimplementuj ten fallback w swojej walidacji:

async function getMailServers(domain) {
  // Najpierw spróbuj rekordów MX
  try {
    const mxRecords = await dns.resolveMx(domain);

    if (mxRecords.length > 0) {
      return {
        type: 'MX',
        servers: mxRecords.sort((a, b) => a.priority - b.priority)
      };
    }
  } catch (error) {
    if (error.code !== 'ENODATA') {
      throw error;
    }
  }

  // Fallback na rekord A
  try {
    const aRecords = await dns.resolve4(domain);

    if (aRecords.length > 0) {
      return {
        type: 'A_FALLBACK',
        servers: [{ exchange: domain, priority: 0 }],
        warning: 'Używanie fallbacku rekordu A - nie znaleziono rekordów MX'
      };
    }
  } catch (error) {
    if (error.code !== 'ENODATA') {
      throw error;
    }
  }

  return {
    type: 'NONE',
    servers: [],
    error: 'Nie znaleziono serwerów poczty dla domeny'
  };
}

Wykrywanie rekordów Null MX

RFC 7505 definiuje rekordy "null MX", które wyraźnie wskazują, że domena nie akceptuje poczty e-mail. Te rekordy mają pojedynczy wpis MX z priorytetem 0 i pustą nazwą hosta ("."):

function hasNullMx(mxRecords) {
  if (mxRecords.length === 1) {
    const record = mxRecords[0];
    if (record.priority === 0 &&
        (record.exchange === '.' || record.exchange === '')) {
      return true;
    }
  }
  return false;
}

async function validateDomainMx(domain) {
  const mxResult = await getMxRecords(domain);

  if (!mxResult.success) {
    return mxResult;
  }

  if (hasNullMx(mxResult.records)) {
    return {
      success: false,
      domain,
      error: 'NULL_MX',
      message: 'Domena wyraźnie nie akceptuje poczty e-mail'
    };
  }

  return mxResult;
}

Buforowanie wyszukiwań MX

Wyszukiwania DNS dodają opóźnienie do każdej weryfikacji. Zaimplementuj buforowanie, aby poprawić wydajność:

class MxCache {
  constructor(ttlMs = 3600000) { // Domyślne TTL 1 godzina
    this.cache = new Map();
    this.ttl = ttlMs;
  }

  get(domain) {
    const entry = this.cache.get(domain.toLowerCase());

    if (!entry) return null;

    if (Date.now() > entry.expiry) {
      this.cache.delete(domain.toLowerCase());
      return null;
    }

    return entry.data;
  }

  set(domain, data) {
    this.cache.set(domain.toLowerCase(), {
      data,
      expiry: Date.now() + this.ttl
    });
  }

  // Respektuj wartości TTL DNS, gdy są dostępne
  setWithTtl(domain, data, ttlSeconds) {
    const ttlMs = Math.min(ttlSeconds * 1000, this.ttl);
    this.cache.set(domain.toLowerCase(), {
      data,
      expiry: Date.now() + ttlMs
    });
  }
}

const mxCache = new MxCache();

async function getMxRecordsCached(domain) {
  const cached = mxCache.get(domain);

  if (cached) {
    return { ...cached, fromCache: true };
  }

  const result = await getMxRecords(domain);

  if (result.success) {
    mxCache.set(domain, result);
  }

  return { ...result, fromCache: false };
}

Typowe wzorce rekordów MX

Zrozumienie typowych konfiguracji MX pomaga interpretować wyniki walidacji i identyfikować potencjalne problemy.

Główni dostawcy poczty e-mail

Rozpoznawanie wzorców MX dla głównych dostawców może pomóc w identyfikacji darmowych adresów e-mail:

const knownProviders = {
  'google': [
    'gmail-smtp-in.l.google.com',
    'googlemail-smtp-in.l.google.com',
    'aspmx.l.google.com'
  ],
  'microsoft': [
    'outlook-com.olc.protection.outlook.com',
    'mail.protection.outlook.com'
  ],
  'yahoo': [
    'mta5.am0.yahoodns.net',
    'mta6.am0.yahoodns.net',
    'mta7.am0.yahoodns.net'
  ],
  'protonmail': [
    'mail.protonmail.ch',
    'mailsec.protonmail.ch'
  ]
};

function identifyEmailProvider(mxRecords) {
  const exchanges = mxRecords.map(r => r.exchange.toLowerCase());

  for (const [provider, patterns] of Object.entries(knownProviders)) {
    for (const pattern of patterns) {
      if (exchanges.some(ex => ex.includes(pattern.toLowerCase()))) {
        return provider;
      }
    }
  }

  return 'unknown';
}

Wykrywanie Google Workspace

Domeny Google Workspace (dawniej G Suite) używają serwerów poczty Google, ale nie są darmowymi kontami e-mail:

function isGoogleWorkspace(domain, mxRecords) {
  const isGoogleMx = mxRecords.some(r =>
    r.exchange.toLowerCase().includes('google') ||
    r.exchange.toLowerCase().includes('googlemail')
  );

  // Sprawdź, czy domena nie jest znaną domeną konsumencką Google
  const googleConsumerDomains = ['gmail.com', 'googlemail.com'];
  const isConsumerDomain = googleConsumerDomains.includes(domain.toLowerCase());

  return isGoogleMx && !isConsumerDomain;
}

Wykrywanie samodzielnie hostowanej poczty

Domeny, które hostują własną pocztę e-mail, często mają rekordy MX wskazujące na subdomeny:

function isSelfHosted(domain, mxRecords) {
  const domainParts = domain.toLowerCase().split('.');
  const baseDomain = domainParts.slice(-2).join('.');

  return mxRecords.some(r => {
    const exchange = r.exchange.toLowerCase();
    return exchange.includes(baseDomain) &&
           !isKnownProvider(exchange);
  });
}

function isKnownProvider(exchange) {
  const providers = ['google', 'microsoft', 'yahoo', 'outlook', 'protonmail'];
  return providers.some(p => exchange.includes(p));
}

Walidacja MX w potokach weryfikacji e-mail

Walidacja MX to jeden krok w kompleksowym procesie weryfikacji e-mail. Zrozumienie jej roli pomaga budować skuteczne potoki weryfikacji.

Kolejność weryfikacji

Walidacja MX zazwyczaj występuje wcześnie w potoku weryfikacji:

async function verifyEmail(email) {
  // 1. Walidacja składni (najszybsza, bez sieci)
  const syntaxResult = validateEmailSyntax(email);
  if (!syntaxResult.valid) {
    return { valid: false, reason: 'invalid_syntax', details: syntaxResult };
  }

  const domain = email.split('@')[1];

  // 2. Walidacja rekordów MX (szybkie wyszukiwanie DNS)
  const mxResult = await validateMxRecords(domain);
  if (!mxResult.valid) {
    return { valid: false, reason: 'no_mx_records', details: mxResult };
  }

  // 3. Dodatkowe sprawdzenia (jednorazowe, oparte na rolach, itp.)
  const domainCheck = await checkDomainReputation(domain);
  if (domainCheck.isDisposable) {
    return { valid: true, risky: true, reason: 'disposable_domain' };
  }

  // 4. Weryfikacja SMTP (najwolniejsza, najbardziej dokładna)
  const smtpResult = await verifySmtp(email, mxResult.records);

  return {
    valid: smtpResult.exists,
    deliverable: smtpResult.deliverable,
    mxRecords: mxResult.records,
    provider: mxResult.provider
  };
}

Równoległe wyszukiwania MX

Przy weryfikacji wielu e-maili zrównoleglaj wyszukiwania MX dla różnych domen:

async function verifyEmailsBatch(emails) {
  // Grupuj e-maile według domeny
  const emailsByDomain = {};

  for (const email of emails) {
    const domain = email.split('@')[1];
    if (!emailsByDomain[domain]) {
      emailsByDomain[domain] = [];
    }
    emailsByDomain[domain].push(email);
  }

  // Wyszukaj rekordy MX dla wszystkich domen równolegle
  const domains = Object.keys(emailsByDomain);
  const mxResults = await Promise.all(
    domains.map(domain => getMxRecordsCached(domain))
  );

  // Zmapuj wyniki z powrotem na domeny
  const mxByDomain = {};
  domains.forEach((domain, index) => {
    mxByDomain[domain] = mxResults[index];
  });

  // Przetwarzaj e-maile z danymi MX
  const results = [];

  for (const email of emails) {
    const domain = email.split('@')[1];
    const mx = mxByDomain[domain];

    if (!mx.success) {
      results.push({ email, valid: false, reason: 'invalid_domain' });
      continue;
    }

    // Kontynuuj weryfikację SMTP używając buforowanych danych MX
    const smtpResult = await verifySmtp(email, mx.records);
    results.push({ email, ...smtpResult });
  }

  return results;
}

Obsługa błędów i przypadki brzegowe

Solidna walidacja MX obsługuje różne warunki błędów z wdziękiem.

Obsługa przekroczenia limitu czasu DNS

Problemy sieciowe mogą powodować zawieszanie wyszukiwań DNS. Zaimplementuj obsługę limitów czasu:

async function getMxRecordsWithTimeout(domain, timeoutMs = 10000) {
  const timeoutPromise = new Promise((_, reject) => {
    setTimeout(() => reject(new Error('DNS_TIMEOUT')), timeoutMs);
  });

  try {
    const result = await Promise.race([
      getMxRecords(domain),
      timeoutPromise
    ]);
    return result;
  } catch (error) {
    if (error.message === 'DNS_TIMEOUT') {
      return {
        success: false,
        domain,
        error: 'TIMEOUT',
        message: 'Przekroczono limit czasu wyszukiwania DNS',
        retryable: true
      };
    }
    throw error;
  }
}

Obsługa nieprawidłowych domen

Obsługuj domeny, które są składniowo nieprawidłowe przed próbą wyszukiwania DNS:

function isValidDomain(domain) {
  if (!domain || typeof domain !== 'string') {
    return false;
  }

  // Sprawdź długość
  if (domain.length > 253) {
    return false;
  }

  // Sprawdź prawidłowe znaki i strukturę
  const domainRegex = /^(?!-)[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}$/;

  if (!domainRegex.test(domain)) {
    return false;
  }

  // Sprawdź długość każdej etykiety
  const labels = domain.split('.');
  for (const label of labels) {
    if (label.length > 63) {
      return false;
    }
  }

  return true;
}

async function validateDomainMxSafe(domain) {
  if (!isValidDomain(domain)) {
    return {
      success: false,
      domain,
      error: 'INVALID_DOMAIN',
      message: 'Format domeny jest nieprawidłowy'
    };
  }

  return await getMxRecordsWithTimeout(domain);
}

Obsługa tymczasowych awarii DNS

Awarie DNS mogą być tymczasowe. Zaimplementuj logikę ponawiania z wykładniczym wycofywaniem:

async function getMxRecordsWithRetry(domain, maxRetries = 3) {
  const delays = [1000, 2000, 4000];

  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const result = await getMxRecordsWithTimeout(domain);

    // Nie ponawiaj dla definitywnych błędów
    if (result.success ||
        result.error === 'NXDOMAIN' ||
        result.error === 'ENOTFOUND') {
      return result;
    }

    // Ponawiaj dla tymczasowych błędów
    if (result.retryable && attempt < maxRetries - 1) {
      await sleep(delays[attempt]);
      continue;
    }

    return result;
  }
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

Względy bezpieczeństwa

Walidacja MX wprowadza kwestie bezpieczeństwa, które deweloperzy muszą uwzględnić.

Zapobieganie podszywaniu się DNS

Standardowe zapytania DNS są nieszyfrowane i podatne na podszycia. Rozważ użycie DNS over HTTPS (DoH) dla wrażliwych aplikacji:

const https = require('https');

async function getMxRecordsDoH(domain) {
  const url = `https://cloudflare-dns.com/dns-query?name=${encodeURIComponent(domain)}&type=MX`;

  return new Promise((resolve, reject) => {
    https.get(url, {
      headers: { 'Accept': 'application/dns-json' }
    }, (res) => {
      let data = '';

      res.on('data', chunk => data += chunk);

      res.on('end', () => {
        try {
          const response = JSON.parse(data);

          if (response.Status !== 0) {
            resolve({
              success: false,
              domain,
              error: 'DNS_ERROR',
              status: response.Status
            });
            return;
          }

          const records = (response.Answer || [])
            .filter(a => a.type === 15)
            .map(a => {
              const [priority, exchange] = a.data.split(' ');
              return {
                priority: parseInt(priority),
                exchange: exchange.replace(/\.$/, '')
              };
            })
            .sort((a, b) => a.priority - b.priority);

          resolve({
            success: records.length > 0,
            domain,
            records
          });
        } catch (error) {
          reject(error);
        }
      });
    }).on('error', reject);
  });
}

Ograniczanie szybkości zapytań DNS

Zapobiegaj nadużyciom, ograniczając szybkość zapytań DNS:

class DnsRateLimiter {
  constructor(maxQueriesPerSecond = 100) {
    this.tokens = maxQueriesPerSecond;
    this.maxTokens = maxQueriesPerSecond;
    this.lastRefill = Date.now();
  }

  async acquire() {
    this.refillTokens();

    if (this.tokens > 0) {
      this.tokens--;
      return true;
    }

    // Czekaj na dostępność tokena
    await sleep(1000 / this.maxTokens);
    return this.acquire();
  }

  refillTokens() {
    const now = Date.now();
    const elapsed = now - this.lastRefill;
    const tokensToAdd = (elapsed / 1000) * this.maxTokens;

    this.tokens = Math.min(this.maxTokens, this.tokens + tokensToAdd);
    this.lastRefill = now;
  }
}

const dnsLimiter = new DnsRateLimiter(50);

async function getMxRecordsRateLimited(domain) {
  await dnsLimiter.acquire();
  return getMxRecords(domain);
}

Korzystanie z BillionVerify do walidacji MX

Chociaż samodzielna implementacja walidacji MX ma wartość edukacyjną, profesjonalne usługi weryfikacji e-mail, takie jak BillionVerify, obsługują walidację MX jako część kompleksowej weryfikacji e-mail.

Zalety korzystania z API weryfikacji e-mail

Kompleksowe sprawdzenia

API weryfikacji e-mail BillionVerify łączy walidację MX ze sprawdzaniem składni, weryfikacją SMTP, wykrywaniem jednorazowych e-maili i więcej w jednym wywołaniu API. To eliminuje potrzebę utrzymywania wielu systemów walidacji.

Zoptymalizowana infrastruktura

Profesjonalne usługi utrzymują globalnie rozproszone resolvery DNS, obsługują buforowanie na dużą skalę i optymalizują wydajność dla milionów weryfikacji.

Ciągłe aktualizacje

Konfiguracje serwerów poczty zmieniają się nieustannie. Usługi weryfikacji e-mail stale aktualizują swoje bazy danych znanych dostawców, domen jednorazowych i wzorców serwerów poczty.

Przykład integracji API

async function verifyEmailWithBillionVerify(email) {
  const response = await fetch('https://api.billionverify.com/v1/verify', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.BV_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ email })
  });

  const result = await response.json();

  // Informacje o MX są zawarte w odpowiedzi
  console.log('MX prawidłowe:', result.mx_found);
  console.log('Domena prawidłowa:', result.domain_valid);
  console.log('Czy dostarczalne:', result.is_deliverable);

  return result;
}

Podsumowanie

Walidacja rekordów MX to fundamentalny komponent weryfikacji e-mail, który potwierdza, że domena może odbierać e-mail przed próbą bardziej zasobożernych sprawdzeń. Implementując odpowiednią walidację MX, możesz szybko odfiltrować nieprawidłowe domeny, zoptymalizować wydajność weryfikacji i zbudować bardziej niezawodne aplikacje obsługujące pocztę e-mail.

Kluczowe wnioski dotyczące walidacji rekordów MX:

  1. Zawsze sprawdzaj rekordy MX przed próbą weryfikacji SMTP, aby zaoszczędzić czas i zasoby
  2. Obsługuj fallback na rekord A zgodnie ze standardami RFC dla domen bez rekordów MX
  3. Zaimplementuj buforowanie, aby zmniejszyć narzut wyszukiwań DNS dla powtarzających się walidacji
  4. Rozpoznawaj typowe wzorce, aby identyfikować dostawców poczty e-mail i potencjalne zagrożenia
  5. Obsługuj błędy z wdziękiem z limitami czasu, ponawianiem prób i odpowiednimi komunikatami błędów

Niezależnie od tego, czy budujesz niestandardowy system weryfikacji e-mail, czy integrujesz się z usługą taką jak BillionVerify, zrozumienie rekordów MX pomaga budować lepszą obsługę poczty e-mail w twoich aplikacjach. Zacznij implementować walidację MX już dziś i zrób pierwszy krok w kierunku kompleksowej weryfikacji e-mail.

Zespoły korzystające z Instantly lub Smartlead poprawiają dostarczalność, czyszcząc listy z BillionVerify przed każdą kampanią.

Porównaj BillionVerify z ZeroBounce pod kątem dokładności i szybkości przed wyborem dostawcy weryfikacji.

Leo
LeoFounder, BillionVerify
Informacje o weryfikacji e-mail

Rozpocznij weryfikację dzisiaj

Zacznij weryfikować adresy e-mail z BillionVerify już dziś. Otrzymaj 100 darmowych kredytów po rejestracji - nie wymagana karta kredytowa. Dołącz do tysięcy firm poprawiających ROI z marketingu e-mailowego dzięki dokładnej weryfikacji e-mail.

Nie wymagana karta kredytowa · 100+ darmowych kredytów dziennie · Rozpocznij w 30 sekund

99.9%
Dokładność
Real-time
Szybkość API
$0.00014
Za e-mail
100/day
Darmowe na zawsze