Strategie migracji witryny z używania ciągu user-agent na nowe wskazówki dotyczące klienta użytkownika.
Ciąg znaków User-Agent to ważna powierzchnia biernego odcisku palca w przeglądarkach, która jest trudna do przetworzenia. Istnieją jednak różne prawidłowe powody gromadzenia i przetwarzania danych użytkownika, więc potrzebna jest droga do lepszego rozwiązania. Wskazówki klienta User-Agent zapewniają zarówno wyraźny sposób zadeklarowania potrzebnych danych User-Agent, jak i metody zwracania tych danych w łatwym w użyciu formacie.
Z tego artykułu dowiesz się, jak sprawdzić dostęp do danych dotyczących klienta użytkownika i jak przenieść użycie ciągu klienta użytkownika do wskazówek dotyczących klienta użytkownika.
Kontrola zbierania i wykorzystywania danych użytkownika
Podobnie jak w przypadku każdej formy gromadzenia danych, musisz zawsze wiedzieć, dlaczego to robisz. Pierwszym krokiem, niezależnie od tego, czy podejmiesz jakieś działania, jest ustalenie, gdzie i po co używasz danych użytkownika.
Jeśli nie wiesz, czy i gdzie są używane dane klienta użytkownika, poszukaj w kodzie front-endu informacji o użyciu navigator.userAgent
, a w kodzie back-endu – o użyciu nagłówka HTTP User-Agent
. Sprawdź też kod front-endu pod kątem używania funkcji, które zostały wycofane, takich jak navigator.platform
i navigator.appVersion
.
Z funkcjonalnego punktu widzenia zastanów się, gdzie w kodzie odbywa się nagrywanie lub przetwarzanie:
- Nazwa lub wersja przeglądarki
- Nazwa lub wersja systemu operacyjnego
- Marka lub model urządzenia
- typ procesora, architektura lub liczba bitów (np. 64-bitowa);
Prawdopodobnie do przetwarzania użytkownika używasz biblioteki lub usługi innej firmy. W takim przypadku sprawdź, czy aktualizują się do obsługi wskazówek dotyczących klienta użytkownika.
Czy używasz tylko podstawowych danych użytkownika?
Domyślny zestaw wskazówek dotyczących klienta użytkownika obejmuje:
Sec-CH-UA
: nazwa przeglądarki i główna wersjaSec-CH-UA-Mobile
: wartość logiczna wskazująca urządzenie mobilneSec-CH-UA-Platform
: nazwa systemu operacyjnego- Pamiętaj, że ta zmiana została uwzględniona w specyfikacji i wkrótce zostanie odzwierciedlona w Chrome i innych przeglądarkach opartych na Chromium.
Proponowana wersja uproszczona ciągu znaków user-agent zachowa te podstawowe informacje w sposób zgodny ze starszymi wersjami. Na przykład zamiast Chrome/90.0.4430.85
ciąg znaków zawiera Chrome/90.0.0.0
.
Jeśli sprawdzasz tylko ciąg znaków User-Agent pod kątem nazwy przeglądarki, wersji głównej lub systemu operacyjnego, Twój kod będzie nadal działać, ale prawdopodobnie zobaczysz ostrzeżenia o wycofaniu.
Chociaż możesz i powinieneś przejść na wskazówki dotyczące klienta użytkownika, możesz mieć starszy kod lub ograniczenia zasobów, które uniemożliwiają Ci to. Zmniejszenie ilości informacji w ciągu user-agenta w taki sposób, aby zachować zgodność wsteczną, ma na celu zapewnienie, że chociaż istniejący kod będzie otrzymywać mniej szczegółowe informacje, to zachowa podstawowe funkcje.
Strategia: interfejs JavaScript API po stronie klienta na żądanie
Jeśli obecnie używasz parametru navigator.userAgent
, przed przejściem na parsowanie ciągu user-agent powinieneś preferować parametr navigator.userAgentData
.
if (navigator.userAgentData) {
// use new hints
} else {
// fall back to user-agent string parsing
}
Jeśli sprawdzasz wersję mobilną lub komputerową, użyj wartości logicznej mobile
:
const isMobile = navigator.userAgentData.mobile;
userAgentData.brands
to tablica obiektów z właściwościami brand
i version
, w których przeglądarka może podać informacje o zgodności z tymi markami. Możesz uzyskać do niego dostęp bezpośrednio jako tablicy lub użyć wywołania some()
, aby sprawdzić, czy występuje w niej określony wpis:
function isCompatible(item) {
// In real life you most likely have more complex rules here
return ['Chromium', 'Google Chrome', 'NewBrowser'].includes(item.brand);
}
if (navigator.userAgentData.brands.some(isCompatible)) {
// browser reports as compatible
}
Jeśli potrzebujesz bardziej szczegółowej wartości identyfikatora użytkownika o wysokiej entropii, musisz ją podać i sprawdzić wynik zwrócony w wartości Promise
:
navigator.userAgentData.getHighEntropyValues(['model'])
.then(ua => {
// requested hints available as attributes
const model = ua.model
});
Możesz też użyć tej strategii, jeśli chcesz przejść z przetwarzania po stronie serwera na przetwarzanie po stronie klienta. Interfejs JavaScript API nie wymaga dostępu do nagłówków żądań HTTP, więc wartości klienta użytkownika można poprosić w dowolnym momencie.
Strategia: statyczny nagłówek po stronie serwera
Jeśli na serwerze używasz nagłówka User-Agent
, a Twoje potrzeby dotyczące tych danych są stosunkowo spójne w całej witrynie, możesz określić odpowiednie wskazówki klienta jako zestaw statyczny w odpowiedziach. Jest to stosunkowo proste podejście, ponieważ wystarczy skonfigurować je w jednym miejscu. Może to być na przykład konfiguracja serwera WWW, jeśli nagłówki są już dodane, konfiguracja hostingu lub konfiguracja najwyższego poziomu platformy lub frameworku używanego w witrynie.
Rozważ tę strategię, jeśli chcesz przekształcać lub dostosowywać odpowiedzi na podstawie danych użytkownika.
Przeglądarki lub inne klienty mogą podawać różne domyślne wskazówki, dlatego warto określić wszystko, czego potrzebujesz, nawet jeśli jest to domyślne.
Na przykład bieżące ustawienia domyślne Chrome będą wyglądać tak:
⬇️ Nagłówki odpowiedzi
Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA
Jeśli chcesz też otrzymywać w odpowiedziach model urządzenia, wyślij:
⬇️ Nagłówki odpowiedzi
Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platform, Sec-CH-UA
Podczas przetwarzania po stronie serwera należy najpierw sprawdzić, czy został wysłany odpowiedni nagłówek Sec-CH-UA
, a jeśli nie jest on dostępny, przełączyć się na analizowanie nagłówka User-Agent
.
Strategia: delegowanie wskazówek do żądań między domenami
Jeśli wysyłasz żądania zasobów podrzędnych z różnych witryn lub domen, które wymagają wysyłania wskazówek dotyczących klienta User-Agent, musisz wyraźnie określić odpowiednie wskazówki za pomocą zasad dotyczących uprawnień.
Załóżmy na przykład, że https://blog.site
hostuje zasoby na serwerze https://cdn.site
, który może zwracać zasoby zoptymalizowane pod kątem konkretnego urządzenia.
https://blog.site
może poprosić o Sec-CH-UA-Model
podpowiedź, ale musi wyraźnie przekazać ją https://cdn.site
za pomocą nagłówka Permissions-Policy
. Lista wskazówek kontrolowanych przez zasady jest dostępna w przeglądzie projektu Wskazówki dotyczące klienta
Infrastruktura.
⬇️ Odpowiedź od blog.site
, która deleguje podpowiedź
Accept-CH: Sec-CH-UA-Model
Permissions-Policy: ch-ua-model=(self "https://cdn.site")
⬆️ Żądanie do zasobów podrzędnych na cdn.site
zawiera podpowiedź delegowania
Sec-CH-UA-Model: "Pixel 5"
Możesz podać wiele wskazówek dla wielu źródeł, a nie tylko z zakresu ch-ua
:
⬇️ Odpowiedź z blog.site
delegująca wiele wskazówek do wielu źródeł
Accept-CH: Sec-CH-UA-Model, DPR
Permissions-Policy: ch-ua-model=(self "https://cdn.site"),
ch-dpr=(self "https://cdn.site" "https://img.site")
Strategia: delegowanie podpowiedzi do elementów iframe
Elementy iframe między domenami działają podobnie jak zasoby między domenami, ale w atrybucie allow
musisz podać wskazówki, które chcesz delegować.
⬇️ Odpowiedź użytkownika blog.site
Accept-CH: Sec-CH-UA-Model
↪️ HTML dla blog.site
<iframe src="https://widget.site" allow="ch-ua-model"></iframe>
⬆️ Prośba do: widget.site
Sec-CH-UA-Model: "Pixel 5"
Atrybut allow
w ramce iframe zastąpi dowolny nagłówek Accept-CH
, który może wysłać widget.site
, więc upewnij się, że uwzględniono wszystko, czego potrzebuje strona iframe.
Strategia: dynamiczne wskazówki po stronie serwera
Jeśli w pewnych częściach ścieżki użytkownika potrzebujesz większej liczby podpowiedzi niż w pozostałych częściach witryny, możesz poprosić o te podpowiedzi na żądanie, a nie statycznie w całej witrynie. Jest to bardziej skomplikowane, ale jeśli masz już ustawione różne nagłówki dla poszczególnych tras, może to być możliwe.
Pamiętaj, że każda instancja nagłówka Accept-CH
nadpisze istniejący zestaw. Jeśli więc nagłówek jest ustawiany dynamicznie, każda strona musi poprosić o pełny zestaw wymaganych wskazówek.
Możesz na przykład mieć w swojej witrynie sekcję, w której chcesz umieścić ikony i elementy sterujące dostosowane do systemu operacyjnego użytkownika. W tym celu możesz dodatkowo zaimportować Sec-CH-UA-Platform-Version
, aby udostępnić odpowiednie zasoby podrzędne.
⬇️ Nagłówki odpowiedzi dla /blog
Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA
⬇️ Nagłówki odpowiedzi dla /app
Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA-Platform-Version, Sec-CH-UA
Strategia: wskazówki po stronie serwera wymagane przy pierwszym żądaniu
Być może w pierwszym żądaniu będziesz potrzebować więcej niż domyślnego zestawu wskazówek, ale jest to mało prawdopodobne, więc sprawdź, czy rozumiesz uzasadnienie.
Pierwsze żądanie to w istocie pierwsze żądanie najwyższego poziomu dla danego źródła, wysłane w ramach danej sesji przeglądania. Domyślny zestaw wskazówek obejmuje nazwę przeglądarki z wersją główną, platformę i wskaźnik mobilności. Pytanie, które tutaj pada, brzmi: czy potrzebujesz rozszerzonych danych dotyczących początkowego wczytania strony?
Aby uzyskać dodatkowe wskazówki dotyczące pierwszej prośby, masz 2 opcje. Po pierwsze, możesz skorzystać z nagłówka Critical-CH
. Ma ono ten sam format co Accept-CH
, ale informuje przeglądarkę, że jeśli pierwsze żądanie zostało wysłane bez istotnej wskazówki, należy od razu ponownie je przesłać.
⬆️ Wstępne żądanie
[With default headers]
⬇️ Nagłówki odpowiedzi
Accept-CH: Sec-CH-UA-Model
Critical-CH: Sec-CH-UA-Model
🔃 Przeglądarka ponownie wysyła początkowe żądanie z dodatkowym nagłówkiem
[With default headers + …]
Sec-CH-UA-Model: Pixel 5
Spowoduje to obciążenie związane z ponownym wysłaniem pierwszego żądania, ale koszt wdrożenia jest stosunkowo niski. Wyślij dodatkowy nagłówek, a przeglądarka zajmie się resztą.
W sytuacjach, gdy naprawdę potrzebujesz dodatkowych wskazówek podczas pierwszego wczytywania strony, propozycja dotycząca niezawodności wskazówek klienta przedstawia sposób określania wskazówek w ustawieniach na poziomie połączenia. W tym celu używa rozszerzenia Application-Layer Protocol Settings(ALPS) do TLS 1.3, aby umożliwić wcześniejsze przekazywanie wskazówek w przypadku połączeń HTTP/2 i HTTP/3. Jest to wciąż bardzo wczesny etap, ale jeśli aktywnie zarządzasz własnymi ustawieniami TLS i połączeń, to jest idealny moment, aby się zaangażować.
Strategia: obsługa starszych wersji
W swojej witrynie możesz mieć kod starszy lub kod zewnętrzny, który zależy od wartości navigator.userAgent
, w tym fragmentów ciągu tekstowego klienta użytkownika, które zostaną skrócone. W długim okresie warto przejść na równoważne
navigator.userAgentData
wybieranie, ale istnieje też tymczasowe rozwiązanie.
UA-CH retrofill to mała biblioteka, która umożliwia zastąpienie wartości navigator.userAgent
nowym ciągiem znaków utworzonym na podstawie wartości navigator.userAgentData
.
Ten kod wygeneruje ciąg znaków klienta użytkownika, który dodatkowo zawiera podpowiedź „model”:
import { overrideUserAgentUsingClientHints } from './uach-retrofill.js';
overrideUserAgentUsingClientHints(['model'])
.then(() => { console.log(navigator.userAgent); });
Wygenerowany ciąg znaków zawiera model Pixel 5
, ale nadal zawiera skrócony model 92.0.0.0
, ponieważ nie przesłano podpowiedzi uaFullVersion
:
Mozilla/5.0 (Linux; Android 10.0; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.0.0 Mobile Safari/537.36
Dodatkowa pomoc
Jeśli te strategie nie pasują do Twojego przypadku użycia, otwórz dyskusję w repozytorium privacy-sandbox-dev-support, a my pomożemy Ci rozwiązać problem.
Zdjęcie: Ricardo Rocha z Unsplash