XMLHttpRequest & JSON

pyretta

Mitglied
Hallo,

ich hab folgendes Problem:
Ich möchte eine JSON, die extern auf einem Server liegt, auf einem mobilen Endgerät verarbeiten und die enthalten Inhalte als News anzeigen lassen.

Der normale Weg, einfach nur "$.getJSON(url, function(data) {..}" zu verwenden, ging leider nicht.
Ich muss erst ein XMLHttpRequest durchführen, um an die JSON zu gelangen.

An die JSON komm ich nun, aber verarbeiten kann ich sie noch nicht. Irgendwie fehlt mir da noch etwas.

Ich habe versucht die "xhr.response" als JSON zu parsen also "JSON.parse(...)" bzw. "$.parseJSON(..)", aber da gab mir die Konsole immer "Object undefined" aus.

Ich hab deshalb dann auch versucht "xhr.responseType = 'json';" hinzuzufügen, das brachte das Programm dann zum Stillstand - nix wurde angezeigt nicht einmal Logs.

Beispiel-Ausgabe von "console.log('xhr.response')" (soweit funktioniert es also, JSON-Lint sagt auch, die Datei wäre valide):
"{"data":{"items":[{"id":"18","tstamp":"1381504148","headline":"irgend eine Überschrift","alias":"seitenalias","date":"1381500960","time":"1381500960","subheadline":"...","teaser":"<p>Artikel-Teaser<\/p>","alt":"Alternativ-Text","path":"files\/images\/bild.jpeg","name":"Autor","text":"<p>Lorem Ipsum<\/p>"}]}}"

Mein Code:
Code:
var xhr = new XMLHttpRequest({mozSystem: true});
		    xhr.open("GET", "http://www.domain.de/json/news.json", true);		    
		    xhr.onreadystatechange = function () {		    	
		    	if(xhr.readyState == 4){
		    		if(xhr.status == 200){
		    			console.log('SUCCESS');
			    		console.log(xhr.response);
			    		
				    	$.getJSON(xhr.response, function(data) {
				    		console.log("getJSON");
							 $.each(data.datas.items, function(i,item) { 	
								
									var title = item.headline;
									var subtitle = item.subheadline;
									var description = item.teaser;
									var content = item.text;
									var pubdate = item.date;
									var creator = item.name;
									var guid = item.alias;
									var imgsrc = item.path;
									var imgalt = item.alt;
									var id = item.id;
									
									var newsimg_src = "";
									var newsimg = "";
									
									if(imgsrc != null){
										newsimg_src = "http://www.domain.de/" + imgsrc;
										newsimg = '<img src="'+newsimg_src+'" alt="'+ title +'" title="'+ title +'" id="img_'+id+'" class="newsimg" />';
									}else{							
										newsimg = '<img src="http://www.tutorials.de/images/content/newsimg_platzhalter.jpg" alt="'+ title +'" title="'+ title +'" id="img_'+id+'" class="newsimg" />';
									}
									
									$('<li class="newsid_'+id+'"><a class="newsid_'+id+'" href="news_detail.html" rel="external" data-transition="slide" onClick="javascript:sessionStorage.newsid=\''+id+'\';"><div class="news_content newsid_'+id+'" data-inline="true"><div class="img_container newsid_'+id+'">'+newsimg+'</div><div class="desc_container newsid_'+id+'"><h3>'+title+'</h3>'+description+'</div><div class="clear"><!-- clear --></div></div></a></li>').appendTo('#newsliste');		   
									
									$('#newsliste').listview('refresh');	
							});					 
				    	});
		    		} 
		    	}
		    }
		
		    xhr.onerror = function (e) {
		    	alert('ERROR: '+ e.error);
		    };
		   	xhr.send(null);

Was mach ich falsch?
Was muss ich anders machen?
Wie bekomme ich eine Ausgabe die auf dem mobilen Endgerät angezeigt werden kann?

Vielen Dank im Voraus für eure Unterstützung.

Gruß,
pyretta
 
Zuletzt bearbeitet:

jeipack

Erfahrenes Mitglied
Wieso ging "$.getJSON(url, function(data) {..}" nicht?

Was wird bei mobilen Endgeräten anders dargestellt?

Weisst du wie die Abfrage ob es Mobile oder Desktop ist aussieht? Wenn ja baue diese mit Chrome Overwrite nach (F12, dann unten Rechts auf Zahnrad -> Overrides -> Enable & User Agend oder Device metrics anklicken), dann kannst du es richtig debuggen.

Meine Vermutung: Du hast bei der Mobileversion kein jQuery, oder aber $ ist nicht als jQuery definiert.
 

pyretta

Mitglied
Hallo jeipack,
vielen Dank für deine Antwort.

das einfache "$getJSON" ging deshalb nicht, da das System des speziellen Endgeräts (Firefox OS) das Aufrufen externer Daten verhindert. Wahrscheinlich aus Sicherheitsgründen. Wäre die Datei auf der gleichen Domain, ginge auch das "$getJSON" ganz normal. Aber da die angeforderte Datei auf einem ganz anderen Server liegt, geht das nicht und ich muss einen XMLHttpRequest durchführen. Bei anderen Endgeräten (Android, iOs, etc.) geht es bereits ohne Probleme mit dem einfachen "$getJSON".

Der Request funktioniert ja auch eigentlich. Die Datei kann aufgerufen werden, aber das allein nützt mir noch nichts. Ich muss sie verarbeiten können, um die News anzuzeigen. Und genau da komm ich im Moment nicht weiter.

Ich brauch also wahrscheinlich eine Alternative zu "$getJSON". Gibt es da was?

Ich hab schon etliche Stunden im Netz recherchiert und einiges ausprobiert, aber nichts hat mir weitergeholfen. Deshalb habe ich hier den Thread eröffnet, in der Hoffnung, Hilfe von den Javascript-Experten des Forums zu bekommen, die sich eventuell schon mit ähnlichen Situationen auseinandersetzen mussten - losgelöst von dem speziellen Endgerät.
 

pyretta

Mitglied
Hallo jeipack,

entschuldige meine verspätete Antwort, ich habe deinen Vorschlag umgesetzt, allerdings gab mir die Konsole dann folgende Fehlermeldung aus:


Das kommt, wenn ich als dataType dein vorgeschlagenes "jsonp" angebe.
Wenn ich "json" angebe, kommt keine Fehlermeldung, allerdings wird es immer noch nicht verarbeitet.

Stehe also leider immer noch vor dem gleichen Problem...

War ja aber schonmal eine gute Idee an dem dataType zu schrauben.
Vielleicht fällt dir oder jemand anderem noch etwas ein...
 

jeipack

Erfahrenes Mitglied
Mit welchem Browser hast du getestet? Chrome gibt meiner Meinung die besten Fehlermeldungen aus.

Aus der Fehlermeldung werde ich nicht schlau (Welcher Codeabschnitt betrifft das?)
 

pyretta

Mitglied
Ich teste es im Firefox mit dem Firefox OS Simulator.
Die Konsole dort ist auch ziemlich gut - finde ich. Mit Chrome kann ich es nicht testen, da es für das Firefox OS Smartphone bestimmt ist. Ich muss also mit der Fehlerkonsole auskommen die ich habe.

Ich verstehe es einfach nicht, wieso es nicht geht.
Der XMLHTTPRequest ist erfolgreich - ich kann die JSON in der Konsole komplett ausgeben lassen ("console.log('xhr.response');") aber "$.getJSON(xhr.response, function(data){....});" geht nicht, bzw. wird gar nicht richtig aufgerufen oder kann nicht aufgerufen/durchgeführt werden.

Habe es getestet:
Code:
$.getJSON(xhr.response, function(data){ console.log('getJSON SUCCESS'); });
Der Konsolen-Text wird nie angezeigt.

Habe es nochmal mit deinem Code versucht - einmal mit "jsonp" und einmal mit "json" - einmal mit "GET" und einmal mit "POST".
Habe dann noch einige Konsolenmeldungen eingefügt, damit ich sehen kann was passiert.

Hier die Ergebnisse im Detail:

Original (mit meiner URL, und Konsolenausgaben):
Code:
 $.ajax({
		        type: "POST",
		        url: "http://www.domain.de/json/news.json",
		        dataType: 'jsonp'
		    }).success(function(data) {
	    		console.log(data);		        
		 
		    }).fail(function(jqXHR, textStatus) {
	    		console.log(textStatus);
	    		console.log(jqXHR);
		    });

Konsolenausgabe:
-------------------------------
data: nix, weil Fehlermeldung: "SyntaxError: invalid label"
textStatus: "parsererror"
jqXHR: [object undefined]

Modifikation mit "GET" und "JSON":
Code:
 $.ajax({
		        type: "GET",
		        url: "http://www.domain.de/json/news.json",
		        dataType: 'json'
		    }).success(function(data) {
	    		console.log(data);		        
		 
		    }).fail(function(jqXHR, textStatus) {
	    		console.log(textStatus);
	    		console.log(jqXHR);
		    });

Konsolenausgabe:
-------------------------------
data: nix
textStatus: "error"
jqXHR: [object undefined]
 
Zuletzt bearbeitet:

jeipack

Erfahrenes Mitglied
Hi
Bist du schon weiter gekommen?
Ich habe mir das ganze nochmals durchgelesen und muss sagen jetzt klingt es für mich so, als würde der Server einfach kein JSONP können..

Hast du Zugriff auf den Server?

Wenn nein dann musst du über PHP den crosssite Request machen und ihn mit Ajax von deinem eigenen Server holen.
Oder, noch ungetestet - gerade gefunden, YQL (Yahoo Query Language) benutzen. Das gibts anscheinend sogar als http://james.padolsey.com/javascript/cross-domain-requests-with-jquery/"]jQuery Plugin, sodass man $.get und $.getJSON wie gewohnt bei jedem crosssite Request benutzen kann.
 
Zuletzt bearbeitet:

pyretta

Mitglied
Hallo jeipack,
entschuldige die verspätete Antwort.
Vielen Dank für deine Hilfsbereitschaft und für die Mühe die du dir machst. Finde ich klasse dass du dran bleibst.

Ja, ich habe es mittlerweile mit Hilfe des Firefox Developer Supports geschafft. An dieser Stelle auch nochmal ein Dankeschön an die Firefox Jungs. Aber ich muss zugeben, da hätte man auch selbst drauf kommen können :D . Ich war sooooo blind.

Es ist eigentlich ganz einfach...
Die "GET"-Anweisung habe ich ja schon im XMLHttpRequest, brauche also keine "$.getJSON" mehr.
Also kann ich direkt mit der "$.each" anfangen.

Dahingehend optimiert sieht es dann so aus:
Code:
var xhr = new XMLHttpRequest({mozSystem: true});
            xhr.open("GET", "http://www.domain.de/json/news.json", true);           
            xhr.onreadystatechange = function () {              
                if(xhr.readyState == 4){
                    if(xhr.status == 200){
                        console.log('SUCCESS');
                        console.log(xhr.response);
                        var data = jQuery.parseJSON( xhr.response );
                             $.each(data.datas.items, function(i,item) {
                                    var title = item.headline;
                                    var subtitle = item.subheadline;
                                    var description = item.teaser;
                                    var content = item.text;
                                    var pubdate = item.date;
                                    var creator = item.name;
                                    var guid = item.alias;
                                    var imgsrc = item.path;
                                    var imgalt = item.alt;
                                    var id = item.id;                                    
                                    var newsimg_src = "";
                                    var newsimg = "";
                                    
                                    if(imgsrc != null){
                                        newsimg_src = "http://www.domain.de/" + imgsrc;
                                        newsimg = '<img src="'+newsimg_src+'" alt="'+ title +'" title="'+ title +'" id="img_'+id+'" class="newsimg" />';
                                    }else{                          
                                        newsimg = '<img src="http://www.tutorials.de/javascript-ajax/.../images/content/newsimg_platzhalter.jpg" alt="'+ title +'" title="'+ title +'" id="img_'+id+'" class="newsimg" />';
                                    }
                                    
                                    $('<li class="newsid_'+id+'"><a class="newsid_'+id+'" href="news_detail.html" rel="external" data-transition="slide" onClick="javascript:sessionStorage.newsid=\''+id+'\';"><div class="news_content newsid_'+id+'" data-inline="true"><div class="img_container newsid_'+id+'">'+newsimg+'</div><div class="desc_container newsid_'+id+'"><h3>'+title+'</h3>'+description+'</div><div class="clear"><!-- clear --></div></div></a></li>').appendTo('#newsliste');         
                                    
                                    $('#newsliste').listview('refresh');    
                            });
                    } 
                }
            }
        
            xhr.onerror = function (e) {
                alert('ERROR: '+ e.error);
            };
            xhr.send(null);

Und auch noch einen kleinen Tipp für angehende Firefox OS Entwickler :D - freundet euch mit der CSP (Content Security Policy) an.
Die verbietet so einiges was man gewöhnt war, was aber gar nicht so schlecht ist. Ein bisschen Entwickler-Erziehung in Sachen Sicherheit kann nicht schaden. Weitere Infos: https://developer.mozilla.org/en-US/Apps/CSP und https://developer.mozilla.org/en-US/docs/Security/CSP/Introducing_Content_Security_Policy

Nochmals vielen, vielen Dank an jeipack!