Tach,
ich habe mich heute mal (wieder) informiert, wie man am besten E-Mail-Adressen auf korrektes Format validiert.
Die Situation
Bisher habe ich in PHP immer den mit Version 5.2.0 eingeführten E-Mail-Filter und in Javascript einen regulären Ausdruck verwendet:
PHP:
function checkEmail($email){
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}
Javascript:
function checkEmail(email){
return email.match(/^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i);
}
Auch HTML5 bietet die Möglichkeit, ein Eingabefeld des Typs E-Mail zu erzeugen:
HTML5:
<!DOCTYPE html>
<html lang="de">
<head>
<title>E-Mail-Validierung</title>
</head>
<body>
<form>
<input type="email">
<input type="submit">
</form>
</body>
</html>
Demo für HTML5 und Javascript.
Das Problem
Das Problem ist nun, dass keine der drei Lösungen IDN-Domains bei E-Mail-Adressen akzeptiert (siehe [1] und [2]). Das heißt Adressen wie foo@bär.de, die durchaus gültig sind, werden als ungültig erkannt.
Die Lösung
Als Lösung muss man also den Domain-Teil in Punycode konvertieren, um danach das Format prüfen zu können.
Für PHP kann man hierzu auf das Modul intl bzw. speziell auf die Funktion idn_to_ascii
zurückgreifen.
PHP:
function checkEmail($email){
$parts = explode('@', $email);
return count($parts) == 2 && filter_var($parts[0].'@'.idn_to_ascii($parts[1]), FILTER_VALIDATE_EMAIL) !== false;
}
Für Javascript bin ich auf eine tolle Bibliothek von Mathias Bynens gestoßen. Damit lässt sich das Problem analog zu PHP lösen.
Javascript:
function checkEmail(email){
var parts = email.split('@');
if(parts.length != 2){
return false;
}
var converted = parts[0] + '@' + punycode.toASCII(parts[1]);
return converted.match(/^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i);
}
Das Fazit
Mit etwas mehr Aufwand ist es in PHP und Javascript also durchaus möglich IDN-E-Mail-Adressen korrekt zu erkennen. Meiner Meinung nach sollten die PHP-Entwickler ihren E-Mail-Filter erweitern, damit er IDN-Domains akzeptiert.
Für HTML5 gibt es dafür keine Lösung, solange die Browser-Entwickler es nicht berücksichtigen. Eingabefelder vom Typ “url” können übrigens mit IDN-Domains umgehen. Warum also nicht auch E-Mail-Felder?
Da davon auszugehen ist, dass sich “Umlautdomains” (wie man so schön sagt) in Zukunft weiter verbreiten werden, wäre es wichtig, dass Browser jetzt schon im vollen Umfang darauf vorbereitet wären.
[1] http://www.php.net/manual/en/filter.filters.validate.php#102398
[2] http://barrow.io/posts/email-validation-of-double-byte-domains/