Archiv der Kategorie: Computer

Bug-Hunting: Download im IE 8 nicht möglich

Es ist schon interessant, dass man sich mit der Fehlerbehebung eines Browsers beschäftigen muss, der vor 5 Jahren das Licht der Welt erblickte und vor 3 Jahren durch den IE 9 abgelöst wurde. 3 Jahre… eine Ewigkeit!

Ein Kundenportal in der Wohnungswirtschaftsbranche kann aber auf den IE 8 nicht verzichten und so bekam ich immer wieder von meinen Kollegen den Hinweis, dass das Kundenportal nicht richtig funktioniert. Die Fehlermeldung der treuen Windows XP-Besitzer und IE8-Surfer beim Download:

Download nicht möglich.

Internet Explorer war nicht in der Lage, diese Seite zu öffnen. Die angeforderte Seite ist entweder nicht verfügbar oder kann nicht gefunden werden. Bitte versuchen Sie es später erneut.

Der Support des Moxiemanagers, den wir für das Kundenportal verwenden, verwies darauf die neueste Version des Moxiemanagers zu installieren, was leider auch nicht half. Ominöserweise funktionierte aber der Download im IE 8 auf der Moxiemanager-Seite. Im Support wurde von „server side issues“ gesprochen. Tja, aber welche potentiellen Issues genau? Vom Support kam darauf leider keine Antwort.

Zu diesem Zeitpunkt fiel mir auf, dass mir ein wesentlicher Unterschied zwischen der funktionierenden Moxiemanager-Seite und unseres Kundenportals entgangen war: Wir verwenden SSL, also HTTPS. Erst dank dieses zusätzlichen Puzzlestücks fand ich bei Google ertragreichere Suchergebnisse: So, dass der Internet Explorer 8  nicht über SSL downloaden kann, wenn ein Header Caching verhindert. Mit Fiddler konnte ich bestätigen, dass entsprechende No-Caching Header beim Kundenportal gesetzt werden. Eigenartig, der Quellcode des Moxiemanagers ist nicht für den Header

[code]Pragma: no-cache[/code]

verantwortlich. Auch gibt es keine Apache-Konfiguration oder .htaccess-Dateien, die für den Header verantwortlich sein können.

Die Lösung: In der php.ini wird über die Einstellung
[code]session.cache_limiter = nocache[/code]
der Header gesetzt. Nach Änderung zu
[code]session.cache_limiter = [/code]
und einem Neustart des Webservers konnte dann auch im IE 8 über SSL heruntergeladen werden.

Rails: Where mit Hash-Bedingung bei Joins

Viele Wege führen nach Rom. So auch bei Abfragen in Rails. Es gibt 3 verschiedene Wege, um Konditionen zu formulieren:

  1. String
  2. Array
  3. Hash

[code lang=“ruby“]class User < ActiveRecord::Base
def self.authenticate_unsafely(user_name, password)
where("user_name = ‚#{user_name}‘ AND password = ‚#{password}’").first
end

def self.authenticate_safely(user_name, password)
where("user_name = ? AND password = ?", user_name, password).first
end

def self.authenticate_safely_simply(user_name, password)
where(:user_name => user_name, :password => password).first
end
end[/code]

Die String-Methode ist unsicher, da die Daten nicht bereinigt werden und so SQL-Injections möglich sind.

Die Array-Methode ist sicher und erinnert syntaktisch stark an Prepared Statements.

Die Hash-Methode ist ebenfalls sicher, aber typisch Rails, weil einfach: lediglich ein Hash wird übergeben. Der Schlüssel (key) als Symbol entspricht der Spaltenbezeichnungen der Tabelle und der Wert (value) definiert die Bedingung.
Das Schöne an der Hash-Methode ist neben der Sicherheit, dass das Hash wesentlich einfacher dynamisch berechnet werden kann (als die Array-Methode):
[code lang=“ruby“]def all_by_employee_or_manager(employee_id=nil, manager_id=nil)
condition = Hash.new
condition[:employee_id] = employee_id unless employee_id.blank?
condition[:manager_id] = manager_id unless manager_id.blank?
where(condition)
end[/code]

Das Problem: NoMethodError

Sobald jedoch in der Abfrage gejoint wird, bekommt man bei einer Hash-Bedingung wie
[code lang=“ruby“]joins(:employees).where(:employees.name => name)[/code]
folgenden Fehler:
[code]NoMethodError: undefined method `name‘ for :employees:Symbol[/code]
Das Problem ist, dass das Symbol :employees.name nicht komplett als Symbol interpretiert wird, sondern nur bis zum Punkt.

Bei der Internetrecherche habe ich für gejointe Abfragen nur Konditionen im String- oder Array-Format finden können, was in meinem Anwendungsfall aber nicht praktikabel war, denn die Konditionen mussten dynamisch berechnet werden.

Die Lösung

Um Konditionen in gejointen Abfragen mit der Hash-Methode anzugeben, muss Ruby klar gemacht werden, dass employees.name komplett als Symbol verstanden werden soll. Das geht so:
[code lang=“ruby“]joins(:employees).where(:"employees.name" => name)[/code]
Einfach, wenn gewusst wie!