JavaScript Das leidige Thema mit den Umlauten, den Zeichenkodierungen und weitere Fragen

S

Slalomser

Gast
Moin,

will nicht wissen wie oft das schon gefragt wurde ... ich suche seit rund 2 Stunden nach der Lösung von meinem Problem und komm nicht weiter. Ich fasse mich kurz, für Fragen bin ich gerne offen.

Ich nutze für mein Kontaktformular folgendes Script: http://www.dustindiaz.com/ajax-contact-form/

1.) Bei mir werden die Umlaute nicht korrekt ausgegeben.
2.) Die versendete Mail erscheint bei mir zweimal im Postkasten.
3.) Mit CC werden die Umlaute nur teils korrekt ausgegeben. Warum auch immer ...

Hier sind die bearbeiteten Quelltexte der Dateien, die mit dem Kontaktformular zusammenhängen. Privates Zeugs hab ich rausgeschnitten. :p

Bin mir ziemlich sicher, das ich die Kodierungen zerhackstückelt hab ... nur, wie ich das richtig machen soll - da bin ich überfragt.

Und danke schon einmal, wenn ihr mir auf die Sprünge helft!! :D

kontakt.html
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> ****** </title>
<meta http-equiv="content-type" content="text/html; charset="utf-8" />

	<link href="design.css" rel="stylesheet" type="text/css" />
    <link rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
    <script type="text/javascript" src="js/functionAddEvent.js"></script>
	<script type="text/javascript" src="js/contact.js"></script>
	<script type="text/javascript" src="js/xmlHttp.js"></script>
	<style type='text/css' media='screen,projection'>
	<!--
		fieldset {
			border: 0px;
			margin: 0px 0px 0px 0px;
			padding: 0px 0px 0px 0px;}
		label {
			display: block;
			margin: 0px 0px 0px 15px;}
		input.text, textarea {
			width: 400px;
			max-width: 400px;
			color: #1D1D1D;
			padding: 5px 5px 5px 5px;
			margin: 5px 5px 5px 15px;
			border: 1px dotted #B5B5B5;}
		input.submit {
			margin: 5px 0px 0px 0px;
			padding: 2px 3px;}
	-->
	</style>
</head>

<body>
	<div id="wrapper">
        <div id="page">
	<div id="contactFormArea">
		<form action="scripts/contact.php" method="post" id="cForm">
			<fieldset>
				<label for="posName">Name:</label>
				<input class="text" type="text" size="25" name="posName" id="posName" />
				<label for="posEmail">E-Mail:</label>
				<input class="text" type="text" size="25" name="posEmail" id="posEmail" />
				<label for="posRegard">Betreff:</label>
				<input class="text" type="text" size="25" name="posRegard" id="posRegard" />
				<label for="posText">Nachricht:</label>
				<textarea cols="50" rows="5" name="posText" id="posText"></textarea>
				<label for="selfCC">
					<input type="checkbox" name="selfCC" id="selfCC" value="send" /> Sende mir bitte eine Kopie an meine Mail-Adresse
				</label>
				<label>
					<input class="submit" type="submit" name="sendContactEmail" id="sendContactEmail" value="Nachricht absenden" />
				</label>
			</fieldset>
		</form>
	</div>
    <p id="loadBar" style="display:none;">
		<strong>Deine E-Mail wird gesendet. Bitte warte einen Moment ...</strong>
	</p>
	<p id="emailSuccess" style="display:none;">
		<strong style="color:green;">Deine E-Mail wurde versendet.</strong>
	</p><br /><br /><br />
           	    </div>
              </div>
            </div>
        <div class="clearfloat">&nbsp;</div>
        <div id="footer">
      	</div>
</body>
</html>

contact.php
PHP:
<?php
// Change the 4 variables below
$yourName = 'unwichtig';
$yourEmail = 'unwichtig';
$yourSubject = 'unwichtig';
$referringPage = 'unwichtig';
// No need to edit below unless you really want to. It's using a simple php mail() function. Use your own if you want
function cleanPosUrl ($str) {
return stripslashes($str);
}
	if ( isset($_POST['sendContactEmail']) )
	{
	$to = $yourEmail;
	$subject = $yourSubject.': '.$_POST['posRegard'];
	$message = cleanPosUrl($_POST['posText']);
	$headers = "von: ".cleanPosUrl($_POST['posName'])." <".$_POST['posEmail'].">\r\n";
	$headers .= 'nach: '.$yourName.' <'.$yourEmail.'>'."\r\n";
	$mailit = mail($to,$subject,$message,$headers);
		if ( @$mailit ) {
		header('Location: '.$referringPage.'?success=true');
		}
		else {
		header('Location: '.$referringPage.'?error=true');
		}
	}
?>

xmlHttpRequest.php
PHP:
<?php
// change the 4 variables below
$yourName = 'unwichtig';
$yourEmail = 'unwichtig';
$yourSubject = 'unwichtig';
$referringPage = 'unwichtig';
// no need to change the rest unless you want to. You could add more error checking but I'm gonna do that later in the official release

header('Content-Type: text/xml');
echo '<?xml version="1.0" encoding="iso-8859-1"?>';

echo '<resultset>';

function cleanPosUrl ($str) {
$nStr = $str;
$nStr = str_replace("**am**","&",$nStr);
$nStr = str_replace("**pl**","+",$nStr);
$nStr = str_replace("**eq**","=",$nStr);
return stripslashes($nStr);
}
	if ( $_GET['contact'] == true && $_GET['xml'] == true && isset($_POST['posText']) ) {
	$to = $yourName;
	$subject = 'Kontaktaufnahme über die Website: '.cleanPosUrl($_POST['posRegard']);
	$message = cleanPosUrl($_POST['posText']);
	$headers = "From: ".cleanPosUrl($_POST['posName'])." <".cleanPosUrl($_POST['posEmail']).">\r\n";
	$headers .= 'To: '.$yourName.' <'.$yourEmail.'>'."\r\n";
	$mailit = mail($to,$subject,$message,$headers);
		
		if ( @$mailit )
		{ $posStatus = 'OK'; $posConfirmation = 'Deine E-Mail wurde versendet.'; }
		else
		{ $posStatus = 'NOTOK'; $posConfirmation = 'Deine E-Mail konnte nicht versendet werden. Versuch es bitte noch einmal.'; }
		
		if ( $_POST['selfCC'] == 'send' )
		{
		$ccEmail = cleanPosUrl($_POST['posEmail']);
		@mail($ccEmail,$subject,$message,"Hallo, hier ist deine gewünschte Kopie aus dem Kontaktformular von URL:");
		}
	
	echo '
		<status>'.$posStatus.'</status>
		<confirmation>'.$posConfirmation.'</confirmation>
		<regarding>'.cleanPosUrl($_POST['posRegard']).'</regarding>
		';
	}
echo'	</resultset>';

?>

contact.js
Code:
function validateFields() {
var frmEl = document.getElementById('cForm');
var posName = document.getElementById('posName');
var posEmail = document.getElementById('posEmail');
var posRegard = document.getElementById('posRegard');
var posText = document.getElementById('posText');
var strCC = document.getElementById('selfCC');
var whiteSpace = /^[\s]+$/;
	if ( posText.value == '' || whiteSpace.test(posText.value) ) {
		alert("Du hast versucht eine leere Nachricht zu senden. Bitte klicke auf OK und fahre weiter fort.");
	}
	else if ( posEmail.value == '' && strCC.checked == true ) {
		alert("Ohne deine E-Mail wird in deinem Postkasten nichts erscheinen können. Gib sie bitte an, damit dies erfolgreich abgeschlossen werden kann.");
		frmEl.reset();
		posName.focus();
	}
	else {
		sendPosEmail();
	}
}
function sendPosEmail () {
	var success = document.getElementById('emailSuccess');
	var posName = document.getElementById('posName');
	var posEmail = document.getElementById('posEmail');
	var posRegard = document.getElementById('posRegard');
	var posText = document.getElementById('posText');
	var strCC = document.getElementById('selfCC').value;
	var page = "scripts/xmlHttpRequest.php?contact=true&xml=true";
	
	showContactTimer(); // quickly begin the load bar
	success.style.display = 'none'; // hide the success bar (incase this is a multi-email
	
	// convert (&, +, =) to string equivs. Needed so URL encoded POST won't choke.
	var str1 = posName.value;
	str1 = str1.replace(/&/g,"**am**");
	str1 = str1.replace(/=/g,"**eq**");
	str1 = str1.replace(/\+/g,"**pl**");
	var str2 = posEmail.value;
	str2 = str2.replace(/&/g,"**am**");
	str2 = str2.replace(/=/g,"**eq**");
	str2 = str2.replace(/\+/g,"**pl**");
	var str3 = posRegard.value;
	str3 = str3.replace(/&/g,"**am**");
	str3 = str3.replace(/=/g,"**eq**");
	str3 = str3.replace(/\+/g,"**pl**");
	var str4 = posText.value;
	str4 = str4.replace(/&/g,"**am**");
	str4 = str4.replace(/=/g,"**eq**");
	str4 = str4.replace(/\+/g,"**pl**");
	
	var stuff = "selfCC="+strCC+"&posName="+str1+"&posEmail="+str2+"&posRegard="+str3+"&posText="+str4;
	loadXMLPosDoc(page,stuff)
}
function showContactTimer () {
	var loader = document.getElementById('loadBar');
	loader.style.display = 'block';
	sentTimer = setTimeout("hideContactTimer()",6000);
}

function hideContactTimer () {
	var loader = document.getElementById('loadBar');
	var success = document.getElementById('emailSuccess');
	var fieldArea = document.getElementById('contactFormArea');
	var inputs = fieldArea.getElementsByTagName('input');
	var inputsLen = inputs.length;
	var tAreas = fieldArea.getElementsByTagName('textarea');
	var tAreasLen = tAreas.length;
	// Hide the load bar alas! Done Loading
	loader.style.display = "none";
	success.style.display = "block";
	success.innerHTML = '<strong style="color:green;">'+grabPosXML("confirmation")+'</strong>';
	// Now Hijack the form elements
	for ( i=0;i<inputsLen;i++ ) {
		if ( inputs[i].getAttribute('type') == 'text' ) {
			inputs[i].value = '';
		}
	}
	for ( j=0;j<tAreasLen;j++ ) {
		tAreas[j].value = '';
	}
}

function ajaxContact() {
var frmEl = document.getElementById('cForm');
addEvent(frmEl, 'submit', validateFields, false);
frmEl.onsubmit = function() { return false; }
}
addEvent(window, 'load',ajaxContact, false);

functionAddEvent.js
Code:
function addEvent(elm, evType, fn, useCapture) {
	if (elm.addEventListener) { 
	elm.addEventListener(evType, fn, useCapture); 
	return true; 
	}
	else if (elm.attachEvent) { 
	var r = elm.attachEvent('on' + evType, fn); 
	EventCache.add(elm, evType, fn);
	return r; 
	}
	else {
	elm['on' + evType] = fn;
	}
}
function getEventSrc(e) {
	if (!e) e = window.event;

	if (e.originalTarget)
	return e.originalTarget;
	else if (e.srcElement)
	return e.srcElement;
}
function addLoadEvent(func) {
var oldonload = window.onload;
	if (typeof window.onload != 'function') {
	window.onload = func;
	} else {
	window.onload = 
		function() {
		oldonload();
		func();
		}
	}
}
var EventCache = function(){
	var listEvents = [];
	return {
		listEvents : listEvents,
	
		add : function(node, sEventName, fHandler, bCapture){
			listEvents.push(arguments);
		},
	
		flush : function(){
			var i, item;
			for(i = listEvents.length - 1; i >= 0; i = i - 1){
				item = listEvents[i];
				
				if(item[0].removeEventListener){
					item[0].removeEventListener(item[1], item[2], item[3]);
				};
				
				/* From this point on we need the event names to be prefixed with 'on" */
				if(item[1].substring(0, 2) != "on"){
					item[1] = "on" + item[1];
				};
				
				if(item[0].detachEvent){
					item[0].detachEvent(item[1], item[2]);
				};
				
				item[0][item[1]] = null;
			};
		}
	};
}();


addEvent(window,'unload',EventCache.flush, false);

xmlHttp.js
Code:
var pos; // variable for posting information
function loadXMLPosDoc(url,posData) {
    // branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) {
        pos = new XMLHttpRequest();
        pos.onreadystatechange = processPosChange;
        pos.open("POST", url, false);
		pos.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        pos.send(posData);
    // branch for IE/Windows ActiveX version
    } else if (window.ActiveXObject) {
        pos = new ActiveXObject("Microsoft.XMLHTTP");
        if (pos) {
            pos.onreadystatechange = processPosChange;
            pos.open("POST", url, false);
			pos.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            pos.send(posData);
        }
    }
}

function grabPosXML (tagName) {
return pos.responseXML.documentElement.getElementsByTagName(tagName)[0].childNodes[0].nodeValue;
}

function processPosChange() {
    // page loaded "complete"
    if (pos.readyState == 4) {
        // page is "OK"
        if (pos.status == 200) {
			if ( grabPosXML("posStatus") == 'NOTOK' ) { 
				alert('There were problems Sending Email. Please check back in a couple minutes');
			}
		}
	}
}
 
Zu A:

Der Mailversand durch die PHP-Funktion mail() hat in der contact.php keinen Content-Type für den Zeichensatz!

PHP:
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n"; 
$headers...hier der rest

Speicherst du die Dateien auch schön brav als UTF8 ohne BOM als Format ab mit deinem Editor?

Zu B:

Evt. liegt es daran das du deine E-Mail Adresse als Absender und im Script die gleiche Adresse als Empfänger ggf. eingetragen hast?

zu C: siehe A.

zu D:

Die XML in der xmlHttpRequest.php wird im "iso-8859-1"-Zeichensatz encodiert. Warum?

PHP:
header('Content-Type: text/xml');
echo '<?xml version="1.0" encoding="iso-8859-1"?>';
 
Zuletzt bearbeitet:
Hi,

erst einmal. Hab mit meinem Wissen versucht, deine Hinweise umzusetzen. Es ist mir noch nicht gelungen.

Die Dateien sind im UTF-8 ohne BOM gespeichert, das stimmt auch soweit.

Der Bereich für die contact.php sieht jetzt so aus: (ist sie soweit auch korrekt?)
PHP:
<?php
// Change the 4 variables below
$yourName = '****';
$yourEmail = '*******';
$yourSubject = '********';
$referringPage = '********';
// No need to edit below unless you really want to. It's using a simple php mail() function. Use your own if you want
function cleanPosUrl ($str) {
return stripslashes($str);
}
	if ( isset($_POST['sendContactEmail']) )
	{
	$to = $yourEmail;
	$subject = $yourSubject.': '.$_POST['posRegard'];
	$message = cleanPosUrl($_POST['posText']);
	$headers = "MIME-Version: 1.0\r\n";
	$headers .= "Content-Type: text/plain; charset=UTF-8\r\n"; 
	$headers = "von: ".cleanPosUrl($_POST['posName'])." <".$_POST['posEmail'].">\r\n";
	$headers .= 'nach: '.$yourName.' <'.$yourEmail.'>'."\r\n";
	$mailit = mail($to,$subject,$message,$headers);
		if ( @$mailit ) {
		header('Location: '.$referringPage.'?success=true');
		}
		else {
		header('Location: '.$referringPage.'?error=true');
		}
	}
?>

Die XML in der xmlHttpRequest.php ist wieder (wie ursprünglich) mit UTF-8 kodiert. Ich dachte nur, das es klappen würde wenn man vom utf-8 wegkommen würd. Frag aber bitte nicht nach dem Sinn, ich ging nach dem Learning by doing Prinzip.
 
PHP:
    $headers = "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: text/plain; charset=UTF-8\r\n"; 
    $headers = "von: ".cleanPosUrl($_POST['posName'])." <".$_POST['posEmail'].">\r\n"; 
    $headers .= "....."

Da ist der Hund begraben (vorletzte Zeile)

Du verkettest vorher die Var $headers mittels .= aber dann überschreibst du die vorherigen Werte einfach und führst dann weiter die Verkettungen aus.

korrekt wäre:

PHP:
    $headers = "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: text/plain; charset=UTF-8\r\n"; 
    $headers .= "von: ".cleanPosUrl($_POST['posName'])." <".$_POST['posEmail'].">\r\n";
    $headers .= 'nach: '.$yourName.' <'.$yourEmail.'>'."\r\n";

(Beachte die "von" Zeile: da steht nun ein .= anstatt =)
Und das kann es schon gewesen sein: den vorher legst Du ja den Content-Type mit dem Zeichensatz fest.
 
Hey, hab deinen Hinweis ausgeführt und leider bekomm ich immer noch die verkehrten Umlaute.

So sieht das in der Mail aus: ä ö ü ß Ü Ä Ö

Natürlich muss ich mich vermehrt mit PHP auseinandersetzen um später eigenständig solche Probleme uz lösen. Nur aktuell bin ich auf dem Gebiet ziemlich hilflos.
 
Sende mal ohne ein XMLRequest eine Mail rein aus Testzwecken).

einfach ein Testscript "test_mail.php" z. B. mit folgendem Code:

PHP:
    $to = 'DEINE@MAILADRESSE';
    $subject = 'UTF8 Mailtest';
    $message = 'Ein einfacher Mailtext: öäüß';
    $headers = "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: text/plain; charset=UTF-8\r\n"; 
    $headers .= "von: Max Mustermann <". $to .">\r\n";
    $headers .= 'nach: Moritz Mustermann <'. $to .'>'."\r\n";
    mail($to,$subject,$message,$headers);

Das die Datei als UTF8 ohne BOM gespeichert werden muss versteht sich von selbst :)
 
Zurück
Oben