Freezing User-Agent Strings

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Es gab Nachrichten darüber, dass Chrome seinen User-Agent-String einfriert (und alle anderen großen Browser sind dabei). Das bedeutet, dass sie immer noch einen User-Agent (UA) String *haben* werden (der in Headern übermittelt wird und in JavaScript als navigator.userAgent verfügbar ist. Indem sie ihn einfrieren, wird er im Laufe der Zeit weniger nützlich für die Erkennung des Browsers/der Plattform/der Version, obwohl der angegebene Grund dafür mehr mit Datenschutz und der Verhinderung von Fingerprinting zu tun hat als mit Entwicklerbedenken.

In der Frontend-Welt lautet der allgemeine Rat: *Sie sollten keine UA-Sniffing betreiben*. Das Hauptproblem ist, dass so viele Websites es falsch machen und die Änderungen, die sie mit diesen Informationen vornehmen, mehr schaden als nützen. Und der allgemeine Rat, dies zu vermeiden, lautet: *Sie sollten basierend auf der Realität dessen testen, was Sie tatsächlich tun wollen*.

Versuchen Sie zu testen, ob ein Browser ein bestimmtes Feature unterstützt? Dann testen Sie *auf dieses Feature*, anstatt auf die abstrahierte Idee eines bestimmten Browsers, der dieses Feature *unterstützen soll*.

In JavaScript sind Features manchmal sehr einfach zu testen, da Sie auf die Anwesenheit ihrer APIs testen.

  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(showPosition);
  } else {
    console.warn("Geolocation not supported");
  }

In CSS haben wir über @supports einen nativen Mechanismus.

@supports (display: grid) {
  .main {
    display: grid;
  }
}

Das wird in JavaScript über eine API freigegeben, die eine boolesche Antwort zurückgibt.

CSS.supports("display: flex");

Nicht alles auf der Webplattform ist so einfach zu testen, aber es ist im Allgemeinen möglich, ohne UA-Sniffing zu betreiben. Wenn Sie in einer schwierigen Situation sind, lohnt es sich immer zu prüfen, ob Modernizr dafür einen Test hat, was sozusagen der Goldstandard für Feature-Tests ist, da er wahrscheinlich kampferprobt ist und mit Randfällen umgegangen ist, die Sie vielleicht nicht vorhersehen können. Wenn Sie die Bibliothek tatsächlich verwenden, erhalten Sie klare logische Abzweigungen.

if (Modernizr.requestanimationframe) {
  // supported
} else {
  // not-supported
}

Was ist, wenn Sie den Browsertyp, die Plattform und die Version *wirklich wissen müssen*? Nun, anscheinend ist diese Information immer noch über eine neue Sache namens User-Agent Client Hints (UA-CH) erhältlich.

Möchten Sie die Plattform wissen? Sie setzen einen Header in der Anfrage namens Sec-CH-Platform und theoretisch erhalten Sie diese Informationen in der Antwort zurück. Sie müssen praktisch danach fragen, was anscheinend ausreicht, um die problematischen Datenschutz-Fingerprinting-Sachen zu verhindern. Es gibt anscheinend auch Header wie Sec-CH-Mobile für mobile Geräte, was ein wenig seltsam ist. Wer entscheidet, was ein „mobiles" Gerät ist? Welche Entscheidungen sollen wir damit treffen?

Informationen über den Browser, die Plattform und die Version auf Serverseite zu kennen, ist oft wünschenswert (um in verschiedenen Situationen unterschiedlichen Code zu senden), genauso wie auf Client-Seite, aber *ohne den Vorteil von Tests*. Vermutlich werden die eingefrorenen UA-Strings lange genug nützlich sein, damit serverseitige Situationen auf UA-CH umstellen können.

Jon Arne Sæterås ist nervös.:

Beruflich habe ich mich über 15 Jahre lang mit dem mobilen Web beschäftigt und gesehen, wie es sich entwickelt, und ich weiß, dass viele, große und kleine Websites auf Geräteerkennung basierend auf dem User-Agent-Header angewiesen sind. Aus Googles Sicht mag es einfach erscheinen, auf das alternative UA-CH umzusteigen, aber hier versteht das Team, das diese Änderung vorantreibt, die Auswirkungen nicht.

Funktionalität, die auf Geräteerkennung basiert, ist kritisch, weit verbreitet und nicht nur im Frontend-Code. Riesige Softwaresysteme mit Backend-Code sind auf Geräteerkennung angewiesen, ebenso wie ganze Infrastruktur-Stacks.

In meiner wichtigsten Codebasis führen wir ein wenig UA-Erkennung auf Serverseite durch. Wir verwenden einen Rails-Gem namens Browser, der UA-abgeleitete Informationen in einer schönen API bereitstellt. Ich kann schreiben

if browser.safari?

end

Wir stellen auch Informationen aus diesem Gem auf der Client-Seite zur Verfügung, damit sie auch dort verwendet werden können. Es gibt nur eine Handvoll Verwendungsfälle für beide, Front- und Back-End, von denen keiner so aussieht, als wäre er besonders schwierig auf andere Weise zu handhaben.

In der Vergangenheit war es ziemlich schwierig, Frontend-Informationen so an den Server weiterzuleiten, dass sie beim ersten Laden der Seite nützlich waren (da der UA keine Informationen wie die Viewport-Größe kennt). Ich erinnere mich an einige ziemlich ausgeklügelte Manöver, bei denen ich eine Skelettseite geladen habe, die ein kleines Stück JavaScript ausführte, das Dinge wie die Messung der Viewport-Breite und Bildschirmgröße tat, dann einen Cookie setzte und die Seite neu lud. Wenn der Cookie vorhanden war, hatte der Server die benötigten Informationen und lud die Skelettseite bei diesen Anfragen gar nicht erst.

Komplizierte Dinge, aber dann hat der Server Informationen über die Viewport-Breite auf Serverseite, was für Dinge nützlich ist, wie das Senden von Assets für kleine Bildschirme (z. B. unterschiedliches HTML), was sonst unmöglich war.

Ich erwähne das, weil UA-CH-Sachen nicht mit den üblichen Client Hints verwechselt werden sollten. Wir sollen unsere Server so konfigurieren können, dass sie einen Accept-CH-Header senden und dann unseren clientseitigen Code dazu bringen, Dinge zurückzusenden, wie zum Beispiel

<meta http-equiv="Accept-CH" content="DPR, Viewport-Width">

Das bedeutet, dass ein Server Informationen vom Client über diese Dinge bei *nachfolgenden* Seitenaufrufen haben kann. Das ist eine schöne API, aber Firefox und Safari unterstützen sie nicht. Ich frage mich, ob sie einen Aufschwung bekommen, wenn beide Browser UA-CH signalisieren, weil diese eingefrorene UA-String-Sache.