Браузерная интеграция NFC: чтение и запись меток без приложений

Браузерная интеграция NFC открывает новые возможности для инвентаризации и автоматизации, но требует точной настройки и обработки исключений. Мы разрабатываем решения, которые позволяют читать и записывать NFC-метки прямо из браузера, без установки приложений. Наша команда реализует проект под ключ — от аудита до внедрения и последующей поддержки, обеспечивая стабильную работу на совместимых устройствах.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Браузерная интеграция NFC: чтение и запись меток без приложений
Средний
от 1 дня до 3 дней
Часто задаваемые вопросы

Вы разработали PWA для инвентаризации склада. Сотрудник подносит телефон к метке NTAG215 — карточка актива подгружается за секунду. Но половина устройств выдают ошибку: «Web NFC недоступен». Или ваши метки NTAG213 не вмещают JSON с несколькими полями. Web NFC API решает эти задачи, но требует правильной настройки и обработки исключений. Мы поможем интегрировать NFC-функциональность в ваш сайт: от простого чтения до полноценной системы записи и синхронизации с API.

Как работает Web NFC API?

Web NFC API предоставляет доступ к NFC-чипу устройства из браузера. Он работает только с NDEF-совместимыми метками (формат обмена данными NFC). Поддержка ограничена Chrome для Android 89+ (desktop, iOS и остальные браузеры отсутствуют). Обязательно HTTPS и жест пользователя (например, нажатие кнопки) для первого запуска. Если поддержки нет — предусматриваем fallback на QR-коды или ручной ввод. Проверить поддержку можно одной строкой: const isSupported = 'NDEFReader' in window.

Какие данные можно хранить на NFC-метках?

NDEF-сообщение может содержать одну или несколько записей. Основные типы: text — текст в кодировке UTF-8 с указанием языка; url — URL-адрес; mime — произвольные данные (например, JSON); smart-poster — вложенная структура с URL, текстом и действием. На практике чаще всего используют JSON для передачи структурированных данных или URL для быстрого перехода. Чем компактнее JSON, тем быстрее чтение: для уменьшения объёма применяйте tree-shake — удаляйте лишние поля.

Сравнение чипов NFC: какой выбрать?

Чип Память Подходит для Цена (условно)
NTAG213 144 байта Один URL или короткий текст Низкая
NTAG215 504 байта URL + текст или небольшой JSON Средняя
NTAG216 888 байт Большой JSON с несколькими полями Выше средней

NTAG215 в 3,5 раза вместительнее NTAG213, при этом лишь на 20% дороже. Для инвентаризации оборудования рекомендуем NTAG215: он оптимален по соотношению ёмкость/цена, позволяет хранить JSON с ID, названием, локацией и временем проверки. Одна метка NTAG215 стоит около $1–1, а экономия от автоматизации достигает $4.5k–6.5k в год.

Типичные ошибки Web NFC API и их обработка

Ошибка Причина Решение
NotAllowedError Пользователь отклонил разрешение Показать сообщение с просьбой разрешить NFC
AbortError Пользователь нажал «Отмена» Просто завершить сценарий
TypeError Неверный формат NDEF-записи Проверить структуру NDEFMessageInit
NotSupportedError Браузер не поддерживает Web NFC Fallback на QR-код или ручной ввод

Чтение NFC-меток: пример кода

Для чтения создаём экземпляр NDEFReader, вызываем scan() и подписываемся на событие reading. При ошибке доступа (NotAllowedError) показываем пользователю понятное сообщение.

class NFCReader {
    private reader: NDEFReader | null = null
    private isReading = false

    async startReading(
        onRecord: (record: NFCRecord) => void,
        onError?: (error: Error) => void
    ): Promise<void> {
        if (!('NDEFReader' in window)) {
            throw new Error('Web NFC не поддерживается в этом браузере')
        }

        this.reader = new NDEFReader()
        this.isReading = true

        try {
            await this.reader.scan()
        } catch (err) {
            if ((err as Error).name === 'NotAllowedError') {
                throw new Error('Разрешение на NFC не предоставлено')
            }
            throw err
        }

        this.reader.addEventListener('reading', (event: NDEFReadingEvent) => {
            console.log(`NFC UID: ${event.serialNumber}`)
            for (const record of event.message.records) {
                onRecord(record)
            }
        })

        this.reader.addEventListener('readingerror', (event) => {
            onError?.(new Error('Ошибка чтения NFC'))
        })
    }

    stop() {
        this.isReading = false
        this.reader = null
    }
}

Для декодирования записей (текст, URL, JSON) используйте утилиту:

interface ParsedNFCRecord {
  type: string
  data: string | Record<string, unknown>
}

function parseNFCRecord(record: NDEFRecord): ParsedNFCRecord {
  switch (record.recordType) {
    case 'text': {
      const decoder = new TextDecoder(record.encoding ?? 'utf-8')
      return {
        type: 'text',
        data: decoder.decode(record.data),
      }
    }
    case 'url': {
      const decoder = new TextDecoder()
      return {
        type: 'url',
        data: decoder.decode(record.data),
      }
    }
    case 'mime': {
      if (record.mediaType === 'application/json') {
        const decoder = new TextDecoder()
        try {
          return {
            type: 'json',
            data: JSON.parse(decoder.decode(record.data)),
          }
        } catch {
          return {
            type: 'text',
            data: decoder.decode(record.data)
          }
        }
      }
      return {
        type: record.mediaType ?? 'binary',
        data: '[binary data]',
      }
    }
    case 'smart-poster': {
      return {
        type: 'smart-poster',
        data: 'Smart Poster record'
      }
    }
    default:
      return {
        type: record.recordType,
        data: '[unknown]'
      }
  }
}

Запись на NFC-метку

Для записи используем NDEFReader.write(). Можно комбинировать URL, текст и JSON:

class NFCWriter {
  async write(data: NFCWriteData): Promise<void> {
    const writer = new NDEFReader()
    const message: NDEFMessageInit = {
      records: this.buildRecords(data),
    }
    await writer.write(message)
    console.log('Запись на метку выполнена')
  }

  private buildRecords(data: NFCWriteData): NDEFRecordInit[] {
    const records: NDEFRecordInit[] = []
    if (data.url) {
      records.push({
        recordType: 'url',
        data: data.url
      })
    }
    if (data.text) {
      records.push({
        recordType: 'text',
        data: data.text,
        lang: 'ru',
      })
    }
    if (data.json) {
      records.push({
        recordType: 'mime',
        mediaType: 'application/json',
        data: new TextEncoder().encode(JSON.stringify(data.json)),
      })
    }
    return records
  }

  async writeWithPassword(message: NDEFMessageInit, password: string): Promise<void> {
    const writer = new NDEFReader()
    await writer.write(message, {
      overwrite: true,
    })
  }
}

interface NFCWriteData {
  url?: string
  text?: string
  json?: unknown
}

Реальный кейс: инвентаризация склада

Мы внедрили Web NFC для клиента из логистики. Каждый стеллаж и единица оборудования были помечены метками NTAG215. Сотрудник открывает PWA на Android, нажимает «Сканировать», подносит телефон — и приложение автоматически подгружает карточку актива из ERP. Ранее процесс занимал 3 минуты ручного ввода, теперь — 15 секунд. Скорость инвентаризации выросла в 12 раз, ошибки ввода исключены. Экономия средств для клиента составила более $4.5k–6.5k в год за счёт снижения простоев и ручного труда.

function AssetInventory() {
  const [scanned, setScanned] = useState<AssetData | null>(null)
  const [isScanning, setIsScanning] = useState(false)
  const readerRef = useRef<NFCReader | null>(null)

  async function startScan() {
    if (!('NDEFReader' in window)) {
      alert('Web NFC недоступен. Используйте Chrome на Android.')
      return
    }

    setIsScanning(true)
    readerRef.current = new NFCReader()
    await readerRef.current.startReading(
      (record) => {
        const parsed = parseNFCRecord(record)
        if (parsed.type === 'json' && isAssetData(parsed.data)) {
          setScanned(parsed.data as AssetData)
          setIsScanning(false)
          readerRef.current?.stop()
        }
      },
      (error) => {
        console.error('NFC error:', error)
        setIsScanning(false)
      }
    )
  }

  function stopScan() {
    readerRef.current?.stop()
    setIsScanning(false)
  }

  return (
    <div>
      {!('NDEFReader' in window) && (
        <div className="bg-yellow-50 border border-yellow-200 rounded p-3 text-sm">
          Web NFC требует Chrome на Android
        </div>
      )}

      <button
        onClick={isScanning ? stopScan : startScan}
        className={`w-full py-4 rounded-xl text-lg font-medium ${
          isScanning ? 'bg-red-500 text-white' : 'bg-blue-600 text-white'
        }`}
      >
        {isScanning ? '⏹ Остановить сканирование' : '📡 Сканировать NFC-метку'}
      </button>

      {isScanning && (
        <div className="text-center py-8 text-gray-500">
          Поднесите метку к задней части телефона...
        </div>
      )}

      {scanned && (
        <AssetCard asset={scanned} onClose={() => setScanned(null)} />
      )}
    </div>
  )
}

Запись меток при инвентаризации

Для первичной маркировки активов используем ту же библиотеку записи:

async function tagAsset(assetId: string, assetData: AssetData) {
  const writer = new NFCWriter()
  await writer.write({
    json: {
      id: assetId,
      name: assetData.name,
      location: assetData.location,
      category: assetData.category,
      lastCheck: new Date().toISOString(),
    },
  })
}

Что входит в интеграцию от нас

  • Анализ требований и выбор подходящих чипов (NTAG213/215/216).
  • Разработка модуля чтения/записи с обработкой всех ошибок (NoPermission, AbortError).
  • UI/UX с большими кнопками и понятными инструкциями для мобильных устройств.
  • Тестирование на реальных метках в различных условиях (освещение, угол поднесения).
  • Документация по интеграции с вашим бэкендом (синхронизация данных).
  • Поддержка после запуска (гарантия 3 месяца).

Сроки: от 2 до 5 дней в зависимости от объёма работ (чтение — 1-2 дня, чтение+запись+синхронизация — 3-5 дней).

Почему выбирают нас?

Мы занимаемся веб-разработкой более 5 лет, реализовали 50+ проектов с интеграцией аппаратных API (NFC, Bluetooth, Camera). Гарантируем, что решение будет работать на 95% Android-устройств с Chrome. Предоставляем демо-стенд для тестирования до начала работ. Закажите интеграцию Web NFC — свяжитесь с нами для консультации. Оценим ваш проект и предложим оптимальное техническое решение.

Более подробно о Web NFC API читайте в MDN Web NFC API.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139
  • Разработка веб-сайта для компании ФИКСПЕР
    Разработка веб-сайта для компании ФИКСПЕР
    1060