Hauptmenü

jsonP - Request

Begonnen von tiptronic, 09 Januar 2012, 11:54:05

Vorheriges Thema - Nächstes Thema

tiptronic

                                                 

Hallo Rudi,

könnte man (Du ;-)) fhem beibringen, auf einen JSONP-Request zu reagieren und statt einem responseString den Callback zurückzuschicken?

Also, statt so:

 http://fhemhost:8083/fhem?cmd=jsonlist&XHR=1


so, wobei die JSONList dann im myJSONPCallback zurückgeschickt wird:

 http://fhemhost:8083/fhem?cmd=jsonlist&XHR=1&callback =myJSONPCallback


Dies ist extrem praktisch um flexibler mit den Restriktionen der SOP umzugehen.

Andy

--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com

rudolfkoenig

                                                   

On Mon, Jan 09, 2012 at 11:54:05AM +0100, Andy Fuchs wrote:
> Hallo Rudi,
>
> könnte man (Du ;-)) fhem beibringen, auf einen JSONP-Request zu reagieren und
> statt einem responseString den Callback zurückzuschicken?

Bitte es mit dem Author des Moduls (Martin Fischer) klaeren, will da erstmal
nicht reinreden.

--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com

tiptronic

                                                 

Hi Rudi,

hm - ist das nicht mehr eine Basis-Funktion, die eigentlich in fhem reingehört? Ich weiß jetzt im Moment leider nicht, wie fhem intern diese Requests abarbeitet. Aber ich dachte fhem schaut sich diese requests immer an:

http://fhemhost:8083/fhem?cmd=list&XHR=1

und könnte somit quasi alles auch als callback zurückschicken

http://fhemhost:8083/fhem?cmd=list&XHR=1&callback=myCallback

-> {result: ...list... }

Gruß

andy

Am 09.01.2012 um 14:23 schrieb Rudolf Koenig:

> On Mon, Jan 09, 2012 at 11:54:05AM +0100, Andy Fuchs wrote:
>> Hallo Rudi,
>>
>> könnte man (Du ;-)) fhem beibringen, auf einen JSONP-Request zu reagieren und
>> statt einem responseString den Callback zurückzuschicken?
>
> Bitte es mit dem Author des Moduls (Martin Fischer) klaeren, will da erstmal
> nicht reinreden.
>
> --
> To unsubscribe from this group, send email to
> fhem-users+unsubscribe@googlegroups.com

--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com

rudolfkoenig

                                                   

> hm - ist das nicht mehr eine Basis-Funktion, die eigentlich in fhem
> reingehört?

Basis-Funktion ist relativ, ich brauche jsonlist nicht :) Es ist aber Teil des
FHEM Verzeichnisses und damit genauso "Basis-Funktion", wie at, notify und
filelog.


> und könnte somit quasi alles auch als callback zurückschicken

Sicher, jsonlist waere auch einfach zu aendern, ich meine aber derjenige der es
gebaut hat, soll erstmal dafuer Support uebernehmen.


> http://fhemhost:8083/fhem?cmd=list&XHR=1&callback=myCallback

Wenn auf der Kommandozeile (== telnet) das als "jsonlist callback myCallback"
aufgerufen werden kann (nachdem man das implementiert hatte :), dann waere
daraus auf HTTP:

  http://fhemhost:8083/fhem?cmd=list+callback+myCallback&XHR=1

--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com

tiptronic

                                                 

Hi Rudi,

mir geht's nicht um jsonlist (das war nur ein Beispiel), sondern um die Möglichkeit den request an fhem als JSONP-Request zu schicken und damit die SOP zu umgehen, indem fhem das Ergebnis in einen callback wickelt.

http://fhemhost:8083/fhem?cmd=get%20myLog%20&XHR=1&callback=MyCallback

Andy

Am 09.01.2012 um 15:44 schrieb Rudolf Koenig:

>> hm - ist das nicht mehr eine Basis-Funktion, die eigentlich in fhem
>> reingehört?
>
> Basis-Funktion ist relativ, ich brauche jsonlist nicht :) Es ist aber Teil des
> FHEM Verzeichnisses und damit genauso "Basis-Funktion", wie at, notify und
> filelog.
>
>
>> und könnte somit quasi alles auch als callback zurückschicken
>
> Sicher, jsonlist waere auch einfach zu aendern, ich meine aber derjenige der es
> gebaut hat, soll erstmal dafuer Support uebernehmen.
>
>
>> http://fhemhost:8083/fhem?cmd=list&XHR=1&callback=myCallback
>
> Wenn auf der Kommandozeile (== telnet) das als "jsonlist callback myCallback"
> aufgerufen werden kann (nachdem man das implementiert hatte :), dann waere
> daraus auf HTTP:
>
>  http://fhemhost:8083/fhem?cmd=list+callback+myCallback&XHR=1
>
> --
> To unsubscribe from this group, send email to
> fhem-users+unsubscribe@googlegroups.com

--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com

tiptronic

                                                 

>>> http://fhemhost:8083/fhem?cmd=list&XHR=1&callback=myCallback
>>
>> Wenn auf der Kommandozeile (== telnet) das als "jsonlist callback myCallback"
>> aufgerufen werden kann (nachdem man das implementiert hatte :), dann waere
>> daraus auf HTTP:
>>
>> http://fhemhost:8083/fhem?cmd=list+callback+myCallback&XHR=1

Auf der CommandLine braucht man das ja auch nicht, da die Same-Origin-Policy ja eine 'künstliche' Schranke im Browser ist.

Aber:
Wo müsste ich denn das reinschreiben (sofern ich es in Perl hinbekomme), dass fhem mir den callback ausfüllt und zurückschickt?

http://fhemhost:8083/fhem?cmd=list&callback=myCallback

Gehört das nicht eigentlich so irgendwie in 01_FHEMWEB.pm rein?

 if($FW_CALLBACK) {
    $FW_RETTYPE = "application/json; charset=$FW_encoding";
...
     print $callback . '(' . $json . ');';
}

Bin für jeden Hinweis dankbar.

Andy

--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com

rudolfkoenig

                                                   

> Gehört das nicht eigentlich so irgendwie in 01_FHEMWEB.pm rein?

Doch, dein SOP Argument hat mich ueberzeugt. Ich meine es macht nur im
Zusammenhang mit XHR Sinn, also sollte im "if($FW_XHR) {" Abschnitt sein.



>  if($FW_CALLBACK) {
>     $FW_RETTYPE = "application/json; charset=$FW_encoding";

Wieso json? eher "text/javascript, wenn es unbeding sein muss.
FHEMWEB hat von jsonlist keine Ahnung, und das ist gut so :)

--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com

tiptronic

                                                 

Am 11.01.2012 um 12:44 schrieb Rudolf Koenig:

>> Gehört das nicht eigentlich so irgendwie in 01_FHEMWEB.pm rein?
>
> Doch, dein SOP Argument hat mich ueberzeugt. Ich meine es macht nur im
> Zusammenhang mit XHR Sinn, also sollte im "if($FW_XHR) {" Abschnitt sein.

Freut mich - und das gibt eine Menge mehr Flexibilität für potentielle Frontends.

Kannst Du das auch reinmachen? Ich trau' mich nicht...

>
>> if($FW_CALLBACK) {
>>    $FW_RETTYPE = "application/json; charset=$FW_encoding";
>
> Wieso json? eher "text/javascript, wenn es unbeding sein muss.
> FHEMWEB hat von jsonlist keine Ahnung, und das ist gut so :)


Ich bin mir nicht sicher, ob der Browser den returntype überhaupt interessiert, weil ja ein Callback zurückkommt (ich tippe mal auf 'nein'). Muss man mal ausprobieren.


Grüße

andy

--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com

rudolfkoenig

                                                   

> mir geht's nicht um jsonlist (das war nur ein Beispiel), sondern um die
> Möglichkeit den request an fhem als JSONP-Request zu schicken und damit die
> SOP zu umgehen, indem fhem das Ergebnis in einen callback wickelt.

Habs eingebaut, aber statt callback habe ich die Variable jsonp genannt. Also:

  http://fhemhost:8083/fhem?cmd=jsonlist&jsonp=MyCallback

XHR ist mit jsonp implicit. Eingecheckt und per fhemupdate zur Verfuegung
gestellt. Bitte testen.

--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com

tiptronic

                                                 

Hallo Rudi,

vielen Dank für das Einbauen vom JSONP. Es funktioniert schon fast ;-)

Allerdings wird bei dem Request ein STRING zurückgegeben, aber der müsste in JSON zurückkommen:

Der Request ist so: 'http:///fhem?cmd=jsonlist&jsonp=?';

und zurück kommt dann sowas:

jsonp2('{
  "ResultSet": "full",
  "Results": [
    {
      "list": "Global",
      "devices": [
        {
          "DEF": "",
          "NAME": "global",
          "NR": "1",
           ...
            "verbose": "3",
            "version": "5.2+SVN from 2012-01-07 ($Id: fhem.pl 1177 2012-01-07 09:00:32Z rudolfkoenig $)"
          },
          "READINGS": []
        }
      ]
    },
 ...
  ],
  "totalResultsReturned": 33
}
');

und ich bekomme: fhem:1SyntaxError: Unexpected EOF

Könntest Du das bitte noch anpassen?

Danke

Andy



Am 11.01.2012 um 12:44 schrieb Rudolf Koenig:

>> Gehört das nicht eigentlich so irgendwie in 01_FHEMWEB.pm rein?
>
> Doch, dein SOP Argument hat mich ueberzeugt. Ich meine es macht nur im
> Zusammenhang mit XHR Sinn, also sollte im "if($FW_XHR) {" Abschnitt sein.
>
>
>
>> if($FW_CALLBACK) {
>>    $FW_RETTYPE = "application/json; charset=$FW_encoding";
>
> Wieso json? eher "text/javascript, wenn es unbeding sein muss.
> FHEMWEB hat von jsonlist keine Ahnung, und das ist gut so :)
>
> --
> To unsubscribe from this group, send email to
> fhem-users+unsubscribe@googlegroups.com

--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com

rudolfkoenig

                                                   

> Allerdings wird bei dem Request ein STRING zurückgegeben, aber der müsste in
> JSON zurückkommen:

Da bin ich dagegen, sonst kann man nur jsonlist als Argument verwenden. Ein
eval wirst Du wohl auch selber hinkriegen :)


> Der Request ist so: 'http:///fhem?cmd=jsonlist&jsonp=?';

Falsch :) Der Request ist so:
  http:///fhem?cmd=jsonlist&jsonp=MyFunc
Wo kommt der ' und ; her?


> und ich bekomme: fhem:1SyntaxError: Unexpected EOF

Kriege ich nicht. Auch bei jsonp=? nicht. Evtl. Proxy?

--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com

tiptronic

                                                 

Am 14.01.2012 um 09:52 schrieb Rudolf Koenig:

>> Allerdings wird bei dem Request ein STRING zurückgegeben, aber der müsste in
>> JSON zurückkommen:
>
> Da bin ich dagegen, sonst kann man nur jsonlist als Argument verwenden. Ein
> eval wirst Du wohl auch selber hinkriegen :)


Nein - das geht nicht, da der Fehler bereits auf Browser-Ebene auftritt, d.h. BEVOR ich überhaupt ein eval ausführen kann (das 'jsonp' wird als Callback interpretiert).

Ausserdem kann man dann eben genau nicht nur jsonlist als Argument verwenden, sondern eben alles. Die Lösung ist eigentlich ganz einfach: Statt dem String zurückzugeben, wrappt man diesen in ein JSON, d.h.

statt
'{ x: [a:1]}'  //also als String - so wie jetzt

macht man:
{ result: '{ x: [a:1]}'}  //JSON

DANN kann man einen eval auf das 'result' machen. Also eval( myReturnedJSON.result)

>> Der Request ist so: 'http:///fhem?cmd=jsonlist&jsonp=?';
>
> Falsch :) Der Request ist so:
>  http:///fhem?cmd=jsonlist&jsonp=MyFunc
> Wo kommt der ' und ; her?

das ' hatte ich nur zum markieren der Zeile benutzt und das ? steht für den Callback Namen:

Wenn ich von meinem Server (sagen wir mal Port 80) diesen Request abschicke:

http://:8083/fhem?cmd=jsonlist&jsonp=MyFunc

dann  erhalte ich im Browser folgendes:
XMLHttpRequest cannot load http://:8083/fhem?cmd=jsonlist&jsonp=MyFunc. Origin http:// is not allowed by Access-Control-Allow-Origin.

Für den Browser sind die unterschiedlichen ports bereits eine Verletzung der SOP.


>> und ich bekomme: fhem:1SyntaxError: Unexpected EOF
>
> Kriege ich nicht. Auch bei jsonp=? nicht. Evtl. Proxy?

Vermutlich, weil Du Deinen Test von auf abschickst. Probier's doch mal von einem anderen Port (oder besser noch: anderen Rechner) aus.

Könntest Du das nochmal probieren? Ich hab' echt alles versucht, aber einen String zurück lässt der Browser nicht.

Gruß

Andy


--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com

rudolfkoenig

                                                   

> Nein - das geht nicht, da der Fehler bereits auf Browser-Ebene auftritt, d.h.
> BEVOR ich überhaupt ein eval ausführen kann (das 'jsonp' wird als Callback
> interpretiert).

Klar doch, das sollte doch auch der Sinn von jsonP sein.

Zitat http://de.wikipedia.org/wiki/JavaScript_Object_Notation
  Im src-Attribut eines

 

Aber vielleicht verstehe ich auch was nicht.

--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com

tiptronic

                                                 

Hi Rudi,

Du hast es nicht ausprobiert, stimmts? ;-)

>  Um die JSON-Daten auf dem Client verarbeiten zu können, verpackt der Server
>  diese als Parameter in eine JavaScript-Funktion, die im Webbrowser bereits
>  definiert ist. Der Name dieser Funktion wird dem Server über einen Query
>  String der URL mitgeteilt.
>
>  


Der Browser führt das aus, was er zurückbekommt, also im aktuellen falle

MyFunc('foo') {}  // geht aber nicht

wohingegen:

MyFunc({'foo':'bar'}) {} // geht

http://bob.pythonmac.org/archives/2005/12/05/remote-json-jsonp/ >

The way JSONP works is simple, but requires a little bit of server-side cooperation. Basically, the idea is that you let the client decide on a small chunk of arbitrary text to prepend to the JSON document, and you wrap it in parentheses to create a valid JavaScript document (and possibly a valid function call).

The client decides on the arbitrary prepended text by using a query argument named jsonp with the text to prepend. Simple! With an empty jsonp argument, the result document is simply JSON wrapped in parentheses.




Ich habe in fhem mal die single-quotes bei       FW_pO "$FW_jsonp('$FW_cmdret');";  entfernt:

      FW_pO "$FW_jsonp($FW_cmdret);";

Dann geht alles wie geschnitten Brot (zumindest mit der JSONList). Möchte man das verallgemeinern gibt es meiner Meinung nach 2 Möglichkeiten:

1.) Wenn $FW_cmdret  am Anfang ein { und am Ende ein } hat, dann schickt man es einfach wie oben zurück, ansonsten macht man vorn und hinten eine Klammer dran.
2. Man wrappt das $FW_cmdret  in ein JSON:

    FW_pO "$FW_jsonp({'jsonresult':'$FW_cmdret'});";

Das wiederum dürfte Ärger machen, wenn man die jsonlist zurückschickt, da diese ja dann als String eingebettet würde.

Egal wie: möchte man das Ergebnis nicht nur auf die jsonlist beschränken, muß man drauf achten, dass der Rückgabewert auch ein gültiges JSON ist, oder ihn encoden.

Mir würde die Variante 1 am besten gefallen.

Mein Perl ist leider viel zu schlecht, sonst würde ich Dir das Snippet schicken :)

Grüße

Andy


>
>  
>
> Aber vielleicht verstehe ich auch was nicht.






>
> --
> To unsubscribe from this group, send email to
> fhem-users+unsubscribe@googlegroups.com

--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com

rudolfkoenig

                                                   

> Du hast es nicht ausprobiert, stimmts? ;-)

Stimmts. Es sollte auch:
  eval('result='+arg);
heissen. Damit geht es. Ausprobiert :)

--
To unsubscribe from this group, send email to
fhem-users+unsubscribe@googlegroups.com