Posts Tagged ‘JavaScript’

Sonntag, 5. März 2017

Ärgernis: Passwortfelder, welche kein Copy & Paste zulassen

Wer nur ein Quäntchen Sicherheitsbewusstsein besitzt, setzt heute Passwortmanager ein und verwendet für jeden Web-Service ein einzigartiges Passwort. Die besten Passwortmanager klinken sich mittlerweile auch mittels Erweiterungen in die Web-Browser ein und erlauben es so, Login-Formulare auf Knopfdruck auszufüllen, ohne dass man noch manuell Copy & Paste machen muss.

Ich verwende 1Password.

Leider scheint diese Technologie noch nicht bei allen Web-Entwicklern angekommen zu sein. Immer wieder stosse ich in meinem Alltag auf Web-Sites, bei denen minderbelichteter, selbsternannter „Security-Spezialist“ entschieden hat, dass Copy & Paste in eine Passwort-Feld ganz, ganz, ganz pöhse ist und deshalb unterbunden werden muss.

Was für mich bedeutet, dass ich das kryptische, 16-stellige Passwort von Hand abtippen muss. Oder aber ich mache mir das Safari Web-Developer-Menu und die JavaScript-Konsole zu nutze und setze das Passwort-Feld halt mit JavaScript-Befehlen (in der Konsole funktioniert Copy & Paste problemlos):

Zuerst finde ich die DOM ID des Passwort-Feldes heraus …

image-7213

… dann wechsle ich in die Konsole und setze den Passwort-Wert:

image-7214

Anschliessend klicke ich in der Web-Ansicht auf „Login“. Et voilà!

Tags: , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Montag, 7. Oktober 2013

Mit Google Docs Spreadsheet eine Variable von einer Internet-Seite abrufen und als Zellwert verwenden

In Google Docs Spreadsheet ist es äusserst einfach, eigene Zellfunktionen zu definieren und diese danach mit einer JavaScript-basierten Funktion zu hinterlegen.

Ich habe mir diese Funktionalität zu Nutzen gemacht, um via meinen Linux-Server die aktuellen Gold- und Silberpreise in Schweizer Franken von einer Web-Site auszulesen und als „rohe“ Zahl an eine Zelle eines Google Docs Spreadsheet weiterzugeben. Basierend auf diesem Wert werden danach weitere Berechnungen in anderen Zellen angestossen.

Zuerst habe ich hierzu ein Spreadsheet eröffnet und sogleich unter Tools > Script editor… ein Script namens „Code.gs“ erstellt. Dort habe ich folgende (hier anonymisierte) JavaScript-Funktion abgelegt:

function getQuote(item) {
  if(item.length < 3) {
    return '#ERROR: parameter too short';
  }
  
  var response = UrlFetchApp.fetch("http://site.tld/index.php?item=" + item + "&raw=true");
  
  quoteRaw = response.getContentText();
  quote = parseFloat(quoteRaw).toFixed(2);
  
  return quote;
}

Anschliessend habe ich in der Zelle A1 den Wert „Gold“ hinterlegt. In Zelle A2 habe ich notiert „=getQuote(A1)“. Sobald man die Zelle A2 verlässt, versucht Google, die URL aufzurufen und die Antwort in eine Zahl umzuwandeln. Dies setzt natürlich voraus, dass das PHP-Script auf dem entfernten keinen HTML-Code zurückgibt, sondern Plaintext. Sobald Google die Funktion getQuote() aufruft, steht in der Zelle für ein bis zwei Sekunden „Thinking…“, während Google im Hintergrund meinen Server kontaktiert und die hinterlegte URL aufruft. Sobald der Wert empfangen wurde, wird dieser in der Zelle angezeigt.

Nebenbemerkung: Ja, den Umweg über meinen eigenen Server könnte ich mir selbstverständlich sparen. Ich bin mir es aber zu Schade, a) ausgedehntes JavaScript zu programmieren, zumal b) Google keine guten Debug-Werkzeuge im Script-Editor bereitstellt. Stattdessen verlasse ich mich auf PHP, Apache und auf dem Server installierte Linux-Tools mit ihren ausgefeilten Funktionen und einem sauberen Debug Logging.

Tags: , , , , ,
Labels: Programmierung

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 22. August 2013

Midori auf Raspberry Pi von jQuery-Effekten entlasten

Mein Raspberry Pi, welcher ein 24″ Dashboard speist, hat sich in den letzten Tagen vermehrt aufgehängt. Dies mag mit einer Aktualisierung der Dashboard-Software zusammenhängen, insbesondere wohl mit Anpassungen am JavaScript-Code.

Ich setze jQuery als JavaScript-Framework ein und steure damit einige visuelle Gimmicks; beispielsweise schwarze Eselsohren an aktualisierten Tiles, welche innert 30 Sekunden nach der Aktualisierung verblassen und dann ganz verschwinden. Auch wird das Doppelpunkt der Zeitanzeige (HH:MM) so animiert, dass es jede zweite Sekunde ausgeblendet wird.

Dies scheint dazu geführt zu haben, dass die schwachbrüstige CPU des Raspberry Pis voll ausgelastet war. Der Browser Midori, welcher als Vollbild läuft, beanspruchte teilweise bis zu 50% CPU-Last und auch das X-Window-System wieso ähnlich hohe Werte auf. Die Load Average des Raspberry Pis war über 1.

Ich entschied mich deshalb, in den JavaScript-Code eine Weiche einzubauen, welche die grafischen Animationen für schwachbrünstige Browser/Systeme auf ein Minimum beschränkte.

Leider hatte die jQuery-eigenen Konfigurationseinstellung Kollateralschäden zur Folge, weshalb ich den Code selber optimieren musste:

jQuery.fx.off = true;

… funktionierte nicht zufriedenstellend.

Nachfolgend einige Konstrukte, die seit gestern Abend in der Produktion laufen:

Browser-Weiche

var browserIsPerformant = true;
if(navigator.userAgent.match(/(Midori)/)) {
	browserIsPerformant = false;
}

Delay statt FadeOuts

An den zwei Orten, wo ich schnelle (250ms – eine Viertelsekunde) und langsame (30000ms – 30 Sekunden) FadeOuts implementiert hatte, baute ich mit der Variable browserIsPerformant eine Weiche ein. jQuery kennt die .delay()-Funktion, mit welcher Aktionen für eine benutzerdefinierte Zeit (Millisekunden) hinausgezögert werden können. Damit konnte ich sicherstellen, dass die Effekte sowohl in der abgespeckten als auch in der Vollversion des Dashboards zur selben Zeit endeten.

Leider kann .delay() nicht auf .toggle(), .show() und .hide() angewendet werden.

Eselsohren

	if(browserIsPerformant) {
		$(obj).children('.updated').fadeToggle(30000);
	}
	else {
		$(obj).children('.updated').delay(30000).fadeOut(1);
	}

Indem ich im else-Abschnitt den Delay auf 30 Sekunden setzte und den fadeOut auf 1 Millisekunde, ergab sich unter Midori neu keine Performance-Einbusse mehr.

Sekundenanzeige (Doppelpunkte)

	if(browserIsPerformant) {
		$('.separator').fadeTo(250,clockSeparatorMap[opacity]);
	}
	else {
		$('.separator').delay(250).fadeTo(1,clockSeparatorMap[opacity]);
	}

Auch hier arbeite ich mit der .delay()-Funktion, setze sie hier aber „nur“ auf 250 Millisekunden. Anschliessen wird der FadeOut innert 1 Millisekunde gemacht.

Nachtrag

Obwohl Midori nach diesen Anpassungen vorerst stabil lief, fror der Browser nach ca. 10 Stunden erneut ein.

Ich entschied mich deshalb, statt Midori auf Chromium zu setzen:

# apt-get install chromium

… und den Google-Browser folgendermassen zu starten (/etc/xdg/lxsession/LXDE/autostart, via Raspberry PI kiosk mode with Chromium.):

@xset s off
@xset -dpms
@xset s noblank

@chromium --kiosk --incognito http://domain.tld/dash

Auch Chromium (Version 22) hat Probleme mit den opulenten jQuery-Animationen, weshalb ich den JavaScript-Code noch ein wenig anpassen musste:

var browserIsPerformant = true;
if(navigator.userAgent.match(/(Midori)/) || navigator.userAgent.match(/(armv6l)/)) {
	browserIsPerformant = false;
}

Chromium trägt aktuell auch die Prozessorplattform im User Agent-String, im Falle von Raspberry Pi ist das ARM.

Tags: , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Samstag, 2. Juni 2012

Bockende Web-Formulare von Hand (sprich: mit etwas JavaScript) absenden

Da versuchte ich also vor einigen Tagen, mich mit Safari unter Mac OS X 10.7 Lion in die Web-Mail-Lösung meines Arbeitgebers einzuloggen — doch bereits beim Eingabeformular für Benutzernamen und Passwort steckte ich fest:

image-5123

Irgendwie fehlte hier der Senden-Button, welcher unter Windows im Microsoft Internet Explorer präsent war! Nun, da ich in meiner Freizeit als Web-Entwickler tätig bin, hatte ich selbstverständlich das Developer-Menu in Safari aktiviert. Dies erlaubte mir nun, mittels Rechtsklick irgendwo in den Hintergrund der Web-Seite zu klicken, Inspect Element auszuwählen und danach zügig in die (JavaScript-)Konsole zu wechseln.

Dort gab ich basierend auf Wissen, welches ich seinerzeit (im letzten Jahrhundert) über SelfHTML erlernt hatte, folgenden Befehl ein, gefolgt von einer Zeilenschaltung (je nach Tastatur Enter oder Return):

document.forms[0].submit();

Und schwupp landete ich auf der nächsten Seite des Web-Mail-Logins. Und dort wurde mir beschieden, dass mein Browser und Computer als unsicher eingestuft seien, weil es nicht möglich sei, ein ActiveX-Plugin zu installieren:

image-5124

Bisher war ich ja immer der Meinung, dass gerade das umgekehrte der Fall ist. Ich helfe ein stattliches Vermögen wetten, dass mein Mac potentiell sicherer als die Windows-Kisten ist, die wir auf der Arbeit benutzen — und ich damit erst noch produktiver bin und das Gerät Zugfahrten ohne Strom länger übersteht, weil nicht hundert Hilfs-, Überwachungs- und Sicherheitsapplikationen im Hintergrund laufen und Strom fressen. Aber bei Corporate IT lernt man ja nie aus …

Nebenbei: Das Thema „Bring your own device“ ging gerade kürzlich im Zusammenhang mit IBM durch die Presse. Und wurde dann auch noch aus anderer Warte kommentiert.

Tags: , , , , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Dienstag, 31. Mai 2011

Wieso man E-Mail-Adressen im Web nicht verschleiern sollte

Alle Jahre wieder erhalte ich Anfragen von besorgten Internet-Nutzern, wieso deren E-Mail-Adresse im Klartext auf Web-Sites erscheint. So könne sie doch problemlos von Spammern entwendet werden, worauf die Mailbox mit unerwünschten Mails überquillt.

Doch:

Spam is a problem for you–obfuscation makes it a problem for your users.

Quelle: Obfuscate no more: why your email address should go au naturale – Jason Priem

Schöner kann man es nicht ausdrücken: Indem ich Mail-Adressen verschlüssle (beispielsweise in der Form spam at emeidi dot com), schütze ich mich vielleicht vor Spam (dabei weiss jeder anständige Web-Entwickler, wie rasch man einen Spider entwickelt hat, der in HTML-Dumps nach „at“ und „dot“ Ausschau hält), aber garantiert auch davor, dass Personen auf gewohnte Weise mit mir Kontakt aufnehmen können — nämlich mit Klick auf meine verlinkte E-Mail-Adresse.

Stattdessen sollten wir unsere Mail-Accounts lieber auf Servern hosten, die gut funktionierende Spam-Filter im Einsatz haben.

Notabene: Natürlich gibt es andere, offenbar sehr gut funktionierende Methoden, die besser wirken — doch unter uns: Soll ich als Web-Entwickler wirklich mühsam Zeit aufwenden, um E-Mail-Adressen über meine ganze Web-Site zu verschlüsseln? Dadurch erhöhen sich höchstens der Wartungsaufwand und die Fehlerquellen.

Tags: , , , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 11. Juni 2008

Firebug für Microsoft Internet Explorer …

… gibt es selbstverständlich nicht.

Wer aber JavaScript-Fehler in dem unangefochten besten und standardkonformsten aller je programmierten Browser debuggen muss, der eigentlich gar nie Fehler produzieren sollte, geht folgendermassen vor:

  1. Download des Microsoft Script Debuggers (via Scripting Debugging in Internet Explorer)
  2. Installation
  3. Konfiguration des Internet Explorers gemäss der Anleitung HOW-TO: Debug JavaScript in Internet Explorer

Nachtrag

Mittlerweile gibt es zusätzlich noch die Internet Explorer Developer Toolbar, die frappant an Firebug erinnert. Selbstverständlich niemals so brauchbar wie das quelloffene Original – Microsoft halt …

Tags: , , , ,
Labels: Web

Keine Kommentare | neuen Kommentar verfassen

Dienstag, 10. Juni 2008

jQuery-Update unter Drupal 5: Murks

Keine grosse Sache, die jQuery-Library aus dem 2006 mit der neuesten 1.2.6 zu ersetzen – wer will schon eine mehr als zwei Jahre alte JavaScript-Library benutzen? Doch ein klitzekleines Detail stört nach dem Upgrade: Nun fehlt plötzlich die „Check all“/“Select all“/“Alles auswählen“-Checkbox bei Tabellen (z.B. um alle Seiten auszuwählen, die man löschen möchte).

Glücklicherweise habe nicht nur ich mich durch die Drupal-Foren gekämpft, sondern auch andere Zeitgenossen. Und einer davon hat sich der darbenden Community angenommen und bietet folgende Lösung für die Datei ./misc/tableselect.js:73 an:

$('form table:has(th.select-all):not(.tableSelect-processed)').each(Drupal.tableSelect);

(Andere Drupal-Entwickler hingegen stehen eher darauf, jQuery zu patchen und veraltete APIs nachzubauen – verstehe ich nicht ganz. Henusode.)

Tags: , ,
Labels: IT, Web

Keine Kommentare | neuen Kommentar verfassen