So verbinden Sie ein Skript mit einer Site eines Drittanbieters

Hallo Habr! Dies ist der erste Beitrag in unserem Blog. Viele Leute kennen uns als Chat für die Site, mit ihm haben wir begonnen, und jetzt nehmen wir führende Positionen im Bereich der Business Messenger ein. Wir haben uns schrittweise zu einer umfassenden Geschäftslösung entwickelt, die Kunden viele Möglichkeiten bietet: Rückruf, Kommunikation mit Kunden über Instant Messenger, soziale Netzwerke, mobile Anwendungen, virtuelle Telefonanlagen, CRM-Funktionen und vieles mehr.

Seit einigen Jahren haben wir viele technische Probleme erfolgreich gelöst, viele interessante Dinge gesammelt und an einigen Stellen natürlich einzigartige Erfahrungen gemacht, natürlich unsere Krücken und Fahrräder. Mit diesem Beitrag beginnen wir eine Reihe von Artikeln, in denen wir unsere Erfahrungen bei der Entwicklung und Erstellung von Prozessen in einem vollständig entfernten Team teilen und über unsere Architektur und technische Lösungen berichten, mit denen wir Hunderttausende von Kunden auf der ganzen Welt effektiv bedienen können.

Bild

Jivosite ist heute:

  • 250.000 Kunden weltweit;
  • 150 Millionen Widget-Impressionen pro Tag;
  • 3,5 Millionen Nachrichten pro Tag;
  • 10 Millionen Chats pro Monat;
  • 1M gleichzeitige Verbindungen;
  • Über 250 Server in Produktion.

Da die meisten Leute uns als Chat für eine Website kennen, werden wir wahrscheinlich damit beginnen. In diesem Artikel zeigen wir Ihnen, wie Sie Ihren Code mit einer Website eines Drittanbieters verbinden und worauf Sie als Beispiel für unsere langjährige Erfahrung in der Arbeit mit Chat achten sollten. Dieser Artikel ist nützlich für diejenigen, die einen Plug-in-Dienst planen oder bereits entwickeln, und einfach für alle, die sich für dieses Thema interessieren.

Einstiegspunkt


Das Theater beginnt mit einem Kleiderbügel und der verbundene Dienst mit einem Einfügecode. Es ist der Einstiegspunkt für jeden Dienst oder jedes Modul auf der Site. In der Regel finden Sie es in den Installationsanweisungen. Danach muss es zum HTML-Code der Site hinzugefügt werden. Anschließend gibt es „magic“, das das Skript auf eine bestimmte Weise lädt und initialisiert.

<script src="https://site.com/file.js"></script> 

Es scheint, dass es einfacher sein könnte, das Skript mit der Site zu verbinden? Standardmäßig müssen Sie dem HTML-Code der Seite nur ein Skript-Tag hinzufügen. Tatsächlich ist dies jedoch eine wichtige Phase, in der viele Fallstricke verborgen sind. Zum Beispiel Benutzeridentifikation, Implementierung eines Sicherungsskript-Ladekanals, Anpassung des Erscheinungsbilds oder der Logik, Seitenladegeschwindigkeit usw. Aber reden wir über alles in Ordnung.

Identifizierung


Nur weil es für niemanden sehr interessant ist, ein Skript zu verbinden, führt das Skript sicher eine Art Logik aus, und diese Logik ist an den Benutzer gebunden. Beispiel: Die Zähler-ID APP_ID aus dem sozialen Netzwerk. In unserem Fall ist dies die ID des erstellten Kommunikationskanals. Das heißt, das Skript sollte den Benutzer in Anforderungen an den Server identifizieren. Um den Client anhand des Einfügecodes zu identifizieren, gibt es drei Implementierungsoptionen.

Variante 1

 <script async src="https://site.com/file.js?id=123"></script> 

Übergeben Sie die ID direkt in den Link zur Datei und werfen Sie sie auf der Serverseite in irgendeiner Weise in das Skript. In diesem Fall muss der Server die ID im laufenden Betrieb in die Datei schreiben oder eine JS-Zeichenfolge mit der ID bilden, mit der file.js geladen wird. Diese Logik ähnelt der Implementierung von JSONP-Anforderungen.


Wir haben lange an diesem Prinzip gearbeitet, aber die Nachteile dieses Ansatzes sind, dass die Leerlauflast auf dem Server und die Notwendigkeit, das Server-Caching zu implementieren, hinzugefügt werden.

Option 2

 <script src="https://site.com/file.js" [async]></script> <script type=”text/javascript”> window.serviceNameId = “123”; // ServiceNameModule.init({id: “123”}); </script> 

Async-Attribut - teilt dem Browser mit, dass nicht auf das Laden des Skripts gewartet werden muss, um das DOM zu erstellen. Das Skript muss sofort nach dem Laden ausgeführt werden. Dies reduziert die Ladezeit der Seite, hat aber auch eine Kehrseite der Münze: Das Skript kann ausgeführt werden, bevor das DOM betriebsbereit ist.

Eine der beliebtesten Implementierungen, einschließlich großer Dienste, macht genau das, nur die Syntax ist unterschiedlich, aber das Wesentliche von allen ist das gleiche.


Dieser Ansatz hat zwei Hauptnachteile: Der erste - der Einbettungscode ist kompliziert und der zweite - die Ausführungsreihenfolge dieses Codes ist sehr wichtig, da sonst nichts funktioniert. Außerdem müssen Sie zwischen Geschwindigkeit (asynchron) und Stabilität (ohne asynchron) wählen. Die meisten wählen die zweite Option.

Option 3

 <script async src="https://site.com/file.js?id=123"></script> 

Übertragen Sie ähnlich wie bei der ersten Option die ID im Link zur Datei, rufen Sie sie jedoch im Browser und nicht auf dem Server ab. Es ist nicht so einfach wie es scheint, aber es ist möglich. Die Browser-API verfügt über eine document.currentScript-Eigenschaft. Sie gibt einen Link zu einem Skript zurück, das geladen ist und derzeit im Browser ausgeführt wird. Wenn Sie dies wissen, können Sie die ID berechnen. Dazu müssen Sie die Eigenschaft document.currentScript.src abrufen und die ID regelmäßig daraus extrahieren.


Es gibt jedoch eine Sache: document.currentScript wird nicht von allen Browsern unterstützt. Für Browser, die diese Eigenschaft nicht unterstützen, haben wir einen interessanten Hack entwickelt. Im Code file.js können Sie eine spezielle "gefälschte" Ausnahme auslösen, die in try / catch eingeschlossen ist. Danach wird die URL des Skripts ausgelöst, in dem der Fehler im Fehlerstapel aufgetreten ist. Die URL enthält die ID, die wir mit der gleichen Regelmäßigkeit erhalten.

Diese Art von Magie wird erhalten, aber es funktioniert. Es gibt keine Probleme mit der Ausführungsreihenfolge, der Einfügecode sieht einfach aus und es gibt keinen Overhead auf dem Server. In den letzten zwei Jahren haben wir genau diesen Ansatz verwendet, obwohl der Einfügecode selbst unterschiedlich ist, das Prinzip jedoch dasselbe ist.

Einstellungen


In den meisten Fällen verfügen Plug-In-Skripte über Einstellungen, die für das Erscheinungsbild oder die Logik der Arbeit verantwortlich sind. Diese Einstellungen müssen in das Plug-In-Skript "geworfen" werden, dafür gibt es zwei grundlegend unterschiedliche Ansätze.

Ansatz Nr. 1

 <script async src="https://site.com/file.js"></script> <script type=”text/javascript”> window.serviceName = {color: “red”, title: “”, ...}; // ServiceNameModule.init({color: “red”, title: “”, ...}); </script> 

Dieser Ansatz umfasst auch das Übergeben der Einstellungen in den GET-Parametern an die Skript-URL, ähnlich wie bei Option 1 aus dem Abschnitt "Identifizierung". Wenn der Client die Einstellungen ändern möchte, muss er den Einbettungscode bearbeiten und auf der Site aktualisieren.


Dies ist gut, da alle Einstellungen auf dem Client gespeichert sind und nicht auf dem Server gespeichert werden müssen. Entwickeln und pflegen Sie die gesamte damit verbundene Geschäftslogik. Der Hauptnachteil dieses Ansatzes ist die Unannehmlichkeit für den Kunden, er muss alles manuell erledigen, und wenn es viele Einstellungen gibt, wird der Einbettungscode zu einem schwer zu pflegenden Blatt, in dem es leicht ist, einen Fehler zu machen. Damit die Updates wirksam werden, müssen Sie die Site aktualisieren. Dies sind die zusätzlichen Gesten von Entwicklern und Administratoren.

Ansatz Nr. 2

 <script async src="https://site.com/file.js?id=123"></script> 

Der zweite Ansatz besteht darin, dass der Client den Einfügecode nicht ändern muss, wenn die Einstellungen geändert werden müssen. Alle Einstellungen werden auf dem Server gespeichert. Um die Einstellungen zu ändern, gehen Sie zum Grafikfeld, ändern Sie die erforderlichen Parameter und klicken Sie auf die Schaltfläche "Speichern". Danach werden die Einstellungen automatisch auf seine Site angewendet!


Sie müssen den Code nicht verstehen und dafür eine Bereitstellung durchführen. Dies kann von einer Person durchgeführt werden, die weit von JavaScript entfernt ist, z. B. einem Manager. Natürlich ist diese Option für Benutzer viel bequemer und einfacher, weshalb wir sie verwenden. Sie müssen jedoch für die Bequemlichkeit bezahlen. Dieser Ansatz erfordert die Entwicklung und Unterstützung der Logik auf dem Server und impliziert eine zusätzliche Belastung des Servers. In den folgenden Artikeln werden wir Ihnen auf jeden Fall erklären, wie wir täglich 150 Millionen solcher Anfragen bearbeiten.

Abwärtskompatibilität


Es ist sehr wichtig, so schnell wie möglich zu einer ausgereiften Version des Einbettungscodes zu gelangen. Da das Aktualisieren der bereits installierten Einfügecodes äußerst schwierig sein wird. Ein Beispiel aus unserer Praxis: In den ersten Versionen haben wir numerische IDs verwendet, diese jedoch aus Sicherheitsgründen durch alphanumerische IDs ersetzt. Es stellte sich heraus, dass es sehr schwierig ist, eine Änderung des bereits installierten Einbettungscodes zu erreichen. Viele Menschen wissen nicht einmal, was HTML ist und wie Websites gestaltet sind. Beispielsweise wurde eine Website von Freiberuflern erstellt, ein Studio oder eine Website wurde über ein CMS / einen Konstruktor erstellt usw. In den meisten Fällen arbeiten unsere Kunden nur mit dem Widget-Einstellungsfeld. Seitdem haben wir in Nginx immer noch eine Karte zum Umschreiben alter IDs in neue IDs mit etwa 40.000 Datensätzen.

 .... /script/widget/config/15**90 /script/widget/config/bqZB**rjW5; /script/widget/config/15**94 /script/widget/config/qtfx**xnTi; /script/widget/config/15**95 /script/widget/config/fqmpa**4YX; /script/widget/config/15**97 /script/widget/config/Vr21g**nuT; /script/widget/config/15**98 /script/widget/config/8NXL5**F8E; /script/widget/config/15**00 /script/widget/config/Th2HN**6RJ; .... 

Aufgrund dieser Funktion sind wir gezwungen, die Abwärtskompatibilität des Einbettungscodes für alle Refactoring-Vorgänge aufrechtzuerhalten, von denen sich etwa 5 in unserem Speicher befanden.

Code-Isolation


Da das Skript mit einer Site eines Drittanbieters verbunden ist, die bereits JavaScript- und CSS-Code für die Site und andere Dienste enthält, besteht das Hauptziel darin, die Site nicht zu beschädigen, damit unser Code die Logik nicht ändert, geschweige denn sie beschädigt. Dies kann ein JavaScript-Fehler sein, der den Ausführungsfluss stoppt, oder Stile, die Site-Stile überschreiben. Der Site-Code kann sich jedoch auch auf das verbundene Skript auswirken. Beispielsweise wird eine Bibliothek verwendet, die die Browser-API ändert. Danach funktioniert der Code nicht mehr oder nicht mehr wie erwartet.

 <script type="text/javascript"> //  mootools.js var JSON = new Hash({ encode: function () {}, decode: function () {} // ... }); //    JSON.parse(json); // Uncaught TypeError: JSON.parse is not a function </script> 

 <style type="text/css"> //      body * { padding: 20px; } form input { display: block; border: 2px solid red; } </style> 


Es gibt verschiedene Möglichkeiten, Code zu isolieren. Sie können beispielsweise Präfixe in JS-Variablen und Abschlüssen verwenden, um den globalen Kontext nicht zu verstopfen, und so etwas wie BEM für Stile verwenden. Am einfachsten ist es jedoch, den Code in einem Iframe auszuführen. Er löst die meisten Isolationsprobleme, legt jedoch bestimmte Einschränkungen fest. Wir verwenden eine Hybridversion. In den folgenden Artikeln erfahren Sie mehr über die Codeisolierung.

Ladestelle blockieren




Onload-Ereignis - tritt auf, nachdem die Webseite vollständig geladen wurde, einschließlich Bildern, Stilen und externen Skripten. Ein wichtiges Merkmal ist, dass auf den meisten Websites JS-Logik, Skripts und Anzeigen von Drittanbietern mit dem Auftreten dieses Ereignisses beginnen. Ein sehr wichtiger Punkt für alle verbundenen Skripte ist es, negative Auswirkungen auf dieses Ereignis zu vermeiden.

Dies geschieht in Fällen, in denen der Server, von dem das Skript geladen wird, lange antwortet oder überhaupt nicht antwortet: Dann wird das Onload-Ereignis verzögert und das weitere Laden der Seite wird im Wesentlichen blockiert. Wenn der Server nicht verfügbar ist, tritt das Onload-Ereignis erst auf, nachdem das Zeitlimit für die Anforderung abgelaufen ist (mehr als 60 Sekunden). Daher „brechen“ Probleme auf dem Skript-Upload-Server im Wesentlichen die Websites, was nicht akzeptabel ist.

Persönliche Erfahrung
In der Vergangenheit habe ich für ein Unternehmen gearbeitet, das eine Website mit gleichzeitigem Online-Online-Dating von 100.000 hatte. In jenen Tagen waren die Schaltflächen „In sozialen Netzwerken teilen“ beliebt. Damit sie auf der Site angezeigt werden, mussten Sie ein Skript (sdk) aus den gewünschten sozialen Netzwerken verbinden. Eines Tages rannten Kollegen zu uns und sagten, dass unsere Website nicht funktioniert! Wir haben uns die Überwachung angesehen, bei der alles normal war, und zunächst haben wir das Problem nicht verstanden. Als sie anfingen, tiefer zu graben, stellten sie fest, dass die CDN-Server von Twitter im Liegen lagen und ihr SDK nicht geladen werden konnte. Dies hinderte uns daran, die Site für ca. 1,5 Minuten zu laden. Das heißt, nach dem Öffnen der Site wurde ein wenig HTML geladen (der Rest des SPA) und erst nach 1,5 Minuten wurde alles geladen, das Zeitlimit für die Anfrage funktionierte. Wir mussten dringend einen Hotfix organisieren und ihr Skript von der Site entfernen. Nachdem wir diese Situation wiederholt hatten, beschlossen wir, den Share-Block überhaupt zu entfernen.

In den ersten Versionen des Einfügecodes haben wir dies nicht berücksichtigt, und bei technischen Problemen auf unserer Seite, um es milde auszudrücken, haben wir unseren Kunden Unannehmlichkeiten bereitet, aber im Laufe der Zeit haben wir es behoben.

Lösung

 <script type='text/javascript'> (function(){ var initCode = function () { // insert script tag }; document.readyState === 'complete' ? initCode() : w.addEventListener('load', initCode, false); })(); </script> 

Die Lösung ist einfach: Sie müssen das Ereignis einer vollständigen Auslastung der Site abonnieren und erst dann das Skript laden. Dazu müssen Sie den Einbettungscode und nicht das Skript-Tag verwenden.

Google Seitengeschwindigkeit




Analyse der mobilen Version von habr.com

Die meisten Leute achten auf die Geschwindigkeit des Ladens der Website, laut vielen Studien wirkt sich dies direkt auf den Gewinn aus, und Suchalgorithmen begannen, die Ladezeit der Seite beim Ranking zu berücksichtigen. In dieser Hinsicht verwenden Websitebesitzer häufig ähnliche Tools, um die Leistung der Website zu bewerten. Daher ist es sehr wichtig, den Code optimal mit der Site zu verbinden, da sich dies direkt auf die Downloadzeit auswirkt.

Dies bedeutet, dass Sie moderne Techniken verwenden müssen, um das Laden von Seiten zu optimieren. Verwenden Sie beispielsweise Gzip, zwischenspeichern Sie statische Dateien und Anforderungen, laden Sie asynchrone Skripte, komprimieren Sie statische Dateien mit modernen Algorithmen wie WebP / Brotli / etc und verwenden Sie andere Optimierungen. Wir führen regelmäßig Audits durch und reagieren auf Warnungen und Empfehlungen, um die aktuellen Anforderungen zu erfüllen.

Cdn


In den ersten Versionen haben wir Statics von Anwendungsservern heruntergeladen. Dieser Ansatz hat jedoch Nachteile: teurer Datenverkehr, Entfernung von Website-Besuchern und übermäßige Belastung des Serverkanals. Sie können den Kanal der Anwendungsserver leicht mit dem Habr-Effekt der Sites verstopfen, da der statische Verkehr sehr "stark" ist.

Um Budget, Stabilität und Netzwerklatenz zu sparen, ist es optimal, Statiken von speziell für diesen Zweck entwickelten Servern zu laden. Sie können vorgefertigte CDN-Anbieter verwenden, aber im großen Maßstab ist dies nicht billig und Sie müssen durch die Funktionen, die dieser oder jener Anbieter bietet, eingeschränkt werden.



Wir haben es einfach implementiert und kostengünstige Server in Russland, Europa und Amerika mit unbegrenztem Datenverkehr und einem breiten Kanal bestellt. Es ist billig, stellt keine Einschränkungen für uns dar, wir können alles für uns selbst anpassen und die Fehlertoleranz wird durch den im Browser funktionierenden Mechanismus sichergestellt. Derzeit wird täglich 1 TB Statik von unseren CDN-Servern geladen.

Fehlertoleranz


Leider ist die Welt nicht perfekt, es kommt zu Bränden, Uplinks fallen, DCs gehen vollständig unter Wasser, ILV blockiert Subnetze und Menschen machen Fehler. Trotzdem ist es notwendig, mit solchen Situationen umgehen zu können und weiter zu arbeiten.

Überwachung
Zuerst müssen Sie verstehen, dass etwas schief gelaufen ist. Sie können natürlich warten, bis Benutzer kommen und sich beschweren. Es ist jedoch besser, Überwachung und Warnungen einzurichten und nach der Veröffentlichung zu überprüfen, ob alles in Ordnung ist. Wir überwachen viele verschiedene Parameter, sowohl Server als auch Client, und wenn etwas schief geht, sehen wir es sofort. Beispielsweise hat die Anzahl der Widget-Downloads oder ein abnormaler Anstieg des Datenverkehrs auf CDN-Servern abgenommen.


Die Gesamtzahl der Widget-Downloads für jede Version

Fehlersammlung
JavaScript ist eine sehr spezifische Sprache und es ist leicht, einen Fehler zu machen. Darüber hinaus ist der Zoo der Browser im modernen Web sehr groß; Was in der neuesten Version von Chrome funktioniert, funktioniert in Safari oder Firefox nicht. Daher ist es sehr wichtig, die Fehlersammlung über den Browser zu konfigurieren und rechtzeitig auf Spitzen zu reagieren. Wenn Ihr Code in einem Iframe funktioniert, können Sie dies tun, indem Sie den globalen window.onerror-Handler verfolgen und im Fehlerfall Daten an den Server senden. Wenn der Code außerhalb des Iframes funktioniert, ist es sehr schwierig, die Fehlersammlung zu implementieren.


Die Gesamtzahl der Fehler aller Websites und Browser


Spezifische Fehlerinformationen

CDN-Failover
Ich habe bereits oben geschrieben, dass alles die Eigenschaft hat zu fallen, daher ist es wichtig, mit diesen Situationen besser umzugehen - automatisch. Wir haben mehrere Phasen des Fallbacks von CDN-Servern durchlaufen, mit dem Handbuch begonnen und schließlich einen Weg gefunden, dies automatisch und optimal für den Browser zu tun.

Im manuellen Modus funktionierte dies einfach: SMS empfingen Administratoren, die sagten, dass das CDN ausgefallen sei, sie führten bestimmte Manipulationen durch, wonach das Widget von Anwendungsservern geladen wurde. Dies kann zwischen 5 Minuten und 2 Stunden dauern.

Um den automatischen Fallback zu implementieren, müssen Sie irgendwie erkennen, dass das Skript geladen wurde, aber dies ist nicht so einfach, wie es scheint. Der Browser bietet keine Möglichkeit, Zwischenzustände des Ladens von Skript-Tags zu überwachen, z. B. das Ereignis onprogress in XMLHttpRequest, sondern meldet nur das Ereignis, wenn das Skript geladen und ausgeführt wird. Es ist auch für eine akzeptable Zeit unmöglich festzustellen, dass der Server derzeit nicht verfügbar ist. Das einzige Fehlerereignis wird nach Ablauf des Anforderungszeitlimits von mehr als 1 Minute ausgelöst. In einer Minute verlässt der Besucher möglicherweise bereits die Seite, das Skript wird jedoch nicht geladen.

Wir haben verschiedene Optionen ausprobiert, einfach und komplex, aber am Ende haben wir eine Ping-Anfrage für einen CDN-Server gestellt. Das funktioniert so: Wir pingen zuerst den CDN-Server an, wenn er geantwortet hat, und laden dann das Widget von ihm. Um dieses Schema für den Browser und unsere Server optimal zu implementieren, verwenden wir eine einfache HEAD-Anforderung (ohne Text). Bei nachfolgenden Downloads tun wir dies erst, wenn die Widget-Version aktualisiert wurde, da sich das Widget bereits im Browser-Cache befindet.


So haben wir eine sehr schnelle und automatische Erkennung der Verfügbarkeit des statischen Servers erhalten und wechseln im Falle eines Sturzes fast unverzüglich zum Backup-Server.

Lader


Um Ihr Skript auf eine Website eines Drittanbieters hochzuladen, müssen Sie viele Punkte berücksichtigen. Es ist jedoch schwierig, diese Logik im Einbettungscode zu implementieren, da sie sich einfach in "Fleisch" verwandelt. Sie müssen dies jedoch noch tun. Dazu haben wir ein kleines Modul erstellt, das all diese Logik „unter der Haube“ verwaltet und den Hauptcode des Widgets lädt. Es wird zuerst geladen und implementiert CDN-Failover, Caching, Abwärtskompatibilität mit alten Einbettungscodes, A / B-Tests, das schrittweise Layout der neuen Version des Widgets und viele andere Funktionen.


So kamen wir schrittweise zu einem Schema, das die Hauptfälle des Ladens und Initialisierens des Widgets abdeckt. Sie hat ihre Wirksamkeit im Laufe der Jahre an einer Vielzahl von verschiedenen Standorten bewiesen. Gleichzeitig bleibt der Einfügecode einfach und universell, da er keine Logik enthält und wir ihn jederzeit ändern können, ohne die Benutzer zu zwingen, den Einfügecode zu ändern.

Dienste von Drittanbietern


Schließlich sollten Dienste von Drittanbietern erwähnt werden, die eine Verbindung zur Website herstellen oder auf irgendeine Weise mit Websites interagieren: Such-Bots, Analysen, verschiedene Parser usw. Diese Dienste hinterlassen einen Eindruck bei der Arbeit, das sollten Sie auch nicht vergessen. Ich werde Ihnen einige Fälle aus unserer Praxis erzählen.

Googlebot
Die Anwendung unseres Betreibers verfügt über die Funktion "Besucher", mit der Sie die Besucher sehen können, die gerade die Website anzeigen, sowie verschiedene Informationen dazu: Uhrzeit auf der Website, Seite, Anzahl der angezeigten Seiten usw. Irgendwann beschwerten sich Kunden darüber, dass sie Besucher von anderen Websites „hängten“, dh auf der Website, auf der iPhones verkauft wurden, einen Kunden, der angeblich eine Seite mit dem Namen „Gesichtscreme kaufen“ hatte. Als sie anfingen, es herauszufinden, stellte sich heraus, dass es GoogleBot war, das beim Wechsel von Site zu Site zuerst LocalStorage zwischengespeichert und anschließend falsche Daten auf den Server übertragen hat.

Die Lösung ist einfach: Der Server begann, Daten von GoogleBot zu ignorieren.

Yandex.Metrica
Die Metrik enthält eine wunderbare Funktion - einen Webbrowser, mit dem Sie sehen können, was der Benutzer in Form eines Screencasts gesehen und getan hat. Zu diesem Zweck zeichnet die Metrik alle Benutzeraktionen auf und führt nach dem Umrunden eines speziellen Metrik-Bots durch Websites dieselben Aktionen aus und zeichnet diese auf. Das Problem war, dass Firefox laut unseren Daten im mobilen Emulationsmodus aktiviert war, um den mobilen Browser des Benutzers zu emulieren, aber der userAgent im Bot war Desktop.

Dies führte dazu, dass beim Anzeigen von Sitzungen für mobile Benutzer im Webbrowser die Desktop-Version des Widgets für Aufzeichnungen geöffnet wurde, obwohl Benutzer tatsächlich die mobile Version geöffnet hatten. Unsere Kunden dachten es und bombardierten uns mit Beschwerden. , , , , .

, , , .


, . , . , , NodeJS , 270 - , .

, !

Source: https://habr.com/ru/post/de452802/


All Articles