Peter Nack: Apache, JS parsen als PHP, Zugriff auf Parameter.

Tach zusammen,

ich sitze jetzt schon seit einigen Stunden an einem recht irrefuehrenden Problem - und ich sehe so langsam immer mehr Baeume.

Ich versuche mal das Szenario korrekt zusammenzufassen und hoffe dabei nichts wesentliches zu vergessen.

1.
Mein Projekt ist mittels htaccess so konfiguriert, dass alle js-Anfragen automatisch auf ein bestimmtes Verzeichnis gemapped werden. D.h. ein einfaches example.org/php.js fuehrt zu example.org/gui/js/php.js
In meiner htaccess steht dafuer:
RewriteRule ([^/]+.js) gui/js/$1 [L]

2.
Die Datei php.js wird durch PHP geparsed.
<Files php.js>
  ForceType application/x-httpd-php
</Files>

3.
In php.js selbst setze ich den entsprechenden Header
header('Content-type: text/javascript');

4.
Die php.js-Datei bekommt beim Einbinden im HTML-Header einen Parameter uebergeben
<script src="php.js?lang=en" type="text/javascript"></script>

5.
Rufe ich die Datei testhalber auf wie folgt
http://example.org/php.js?lang=en
so kann ich wunderbar auf den lang-Parameter mittels $_GET['lang'] zugreifen.

Nun mein Problem.
Fuehre ich das ganze jedoch im Kontext der Seite aus - sprich, wenn ich zb die index.html aufrufe (also nicht die direkte Adresse zum Js-File in der Adresszeile), so habe ich den Zustand, dass mir der Parameter nicht zu Verfuegung steht.

Ein Gedanke ist der, dass es vielleicht daran liegen koennte, dass sich der Aufruf von $_GET in der php.js auf den QueryString der gesamten Seite bezieht, und nicht auf die Parameter, welche ich der Datei beim Include mit uebergeben habe.

Ein weiterer Gedanke ist der, dass ich vielleicht etwas in der htaccess falsch eingestellt habe (Siehe Punkt 1), so dass der QueryString bei Reweiten abhanden kommt.

Wie ich es drehe oder wende, ich komme einfach nicht weiter.

Ich hoffe die Beschreibung war verstaendlich genug? Falls es nicht ersichtlich sein sollte, worum es mir hier geht, so werde ich versuchen das Szenario noch einmal gruendlicher zu erklaeren. Gebt mir einfach bescheid.

Besten Dank fuer's Lesen!

MfG
Peter

  1. Hallo,

    [Q]könnte der Querystring sein.

    RewriteRule ([^/]+.js) gui/js/$1 [LQ]

    ungetestet. Es gibt auch NS, google mal.

    alert(<?php var_dump($_GET)?>);

    würde dir das zeigen.

    Gruß

    jobo

    1. [Q]könnte der Querystring sein.
      RewriteRule ([^/]+.js) gui/js/$1 [LQ]
      ungetestet. Es gibt auch NS, google mal.

      RewriteRule ([^/]+.js) gui/js/$1 [L,QSA]

      mfg Beat

      --
      ><o(((°>           ><o(((°>
         <°)))o><                     ><o(((°>o
      Der Valigator leibt diese Fische
      1. Hallo ihr beiden,

        erstmal ein 'wow' fuer die schnelle Beantwortung. Danke ;-)

        RewriteRule ([^/]+.js) gui/js/$1 [LQ]
        RewriteRule ([^/]+.js) gui/js/$1 [L,QSA]

        Beides fuehrt nicht zum erwuenschten Ergebnis.
        Erstere Version liefert mir einen 500er.
        Bei der zweiten ist der Wert auch nicht vorhanden.

        Mir ist gerade noch etwas aufgefallen, was evtl. auch von Bedeutung sein koennte.
        Ich lasse einige Request ueber einen eigenen RequestHandler laufen.
        Sprich, alle Anfragen, die den String "/switch/" anthalten oder auf "html" enden.

        Ausschnitt:
        RewriteCond %{HTTP_HOST} www.example.org$ [NC]
        RewriteRule ^(.*)$ http://example.org/$1 [R=301,L]
        RewriteRule ^(/switch).*$ RequestHandler.php?reqtype=virtual_location
        RewriteRule ([^/]+.html)$ RequestHandler.php?reqtype=html

        Schaue ich mir zb $_REQUEST oder $_GET an, so sehe ich, dass mir der Wert "reqtype" zu Verfuegung steht. Gehe ich jetzt richtig der Annahme, dass ich an dieser Stelle auch die Parameter uebergeben muss?
        Aber eigentlich greifen die o.g. Regeln ja nicht fuer js-Dateien..

        Danke & MfG
        Peter

        1. Hi,

          RewriteRule ^(/switch).*$ RequestHandler.php?reqtype=virtual_location

          Schaue ich mir zb $_REQUEST oder $_GET an, so sehe ich, dass mir der Wert "reqtype" zu Verfuegung steht. Gehe ich jetzt richtig der Annahme, dass ich an dieser Stelle auch die Parameter uebergeben muss?

          es dürfte (wenn überhaupt) die obige Regel sein, die hier greift. In dem Fall hättest Du die Parameter tatsächlich überschrieben - [QSA] schafft Abhilfe. Allerdings wäre dann immer noch nicht geklärt, warum die selbe URL in unterschiedlichen Arten des Anforderns unterschiedliche Ergebnisse liefert.

          Kannst Du die betreffende Seite, in der die JS-Ressource eingebunden ist, bzw. einen auf das Problem reduzierten Klon, verlinken?

          Cheatah

          --
          X-Self-Code: sh:( fo:} ch:~ rl:| br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
          X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
          X-Will-Answer-Email: No
          X-Please-Search-Archive-First: Absolutely Yes
          1. Hi Cheatah,

            es dürfte (wenn überhaupt) die obige Regel sein, die hier greift. In dem Fall hättest Du die Parameter tatsächlich überschrieben - [QSA] schafft Abhilfe.

            Juhuu!! Dem war so. Nun bekomme ich mittels $_GET sowohl "reqtype" als auch die Parameter, die beim Include mit uebergeben werden.

            Kannst Du die betreffende Seite, in der die JS-Ressource eingebunden ist, bzw. einen auf das Problem reduzierten Klon, verlinken?

            Gerne, aber es ist derzeit noch nichts online ;-)

            Fuer mich ist der Apache noch ein Buch mit sieben Siegeln (naja, vielleicht nur sechs oder fuenf ;-). Bin beeindruckt wie schnell ihr mir helfen konntet.

            Tausend Dank euch allen!

            MfG
            Peter

  2. Hallo,

    ich sitze jetzt schon seit einigen Stunden an einem recht irrefuehrenden Problem - und ich sehe so langsam immer mehr Baeume.

    Zitat #1555 ;-)

    Mein Projekt ist mittels htaccess so konfiguriert, dass alle js-Anfragen automatisch auf ein bestimmtes Verzeichnis gemapped werden. D.h. ein einfaches example.org/php.js fuehrt zu example.org/gui/js/php.js

    Das heißt, eine eventuelle Verzeichnisangabe wird ignoriert. Hmm, der Sinn will mir nicht einleuchten. Aber wenn du meinst ...

    Die php.js-Datei bekommt beim Einbinden im HTML-Header einen Parameter uebergeben
      <script src="php.js?lang=en" type="text/javascript"></script>
    Rufe ich die Datei testhalber auf wie folgt
    http://example.org/php.js?lang=en
    so kann ich wunderbar auf den lang-Parameter mittels $_GET['lang'] zugreifen.

    Works as expected.

    Nun mein Problem.
    Fuehre ich das ganze jedoch im Kontext der Seite aus - sprich, wenn ich zb die index.html aufrufe (also nicht die direkte Adresse zum Js-File in der Adresszeile), so habe ich den Zustand, dass mir der Parameter nicht zu Verfuegung steht.

    Most unexpected. Das ist überhaupt nicht einzusehen.
    Hast du kontrolliert, dass der Request, mit dem das Script angefordert wird, derselbe ist wie beim Aufruf "von Hand"? Vor allem, dass der URL-Parameter tatsächlich übermittelt wird? (Diagnosemöglichkeiten: LiveHTTP Extension, Firebug, Server Log)

    Ein Gedanke ist der, dass es vielleicht daran liegen koennte, dass sich der Aufruf von $_GET in der php.js auf den QueryString der gesamten Seite bezieht, und nicht auf die Parameter, welche ich der Datei beim Include mit uebergeben habe.

    Nein. Das läuft doch serverseitig ab. Der Webserver (bzw. der PHP-Interpreter) weiß nichts davon, dass der aktuelle Request irgendwas mit einer HTML-Ressource zu tun hat, die irgendwann vorher abgerufen wurde (wenn nicht zufällig jemand den Referer auswertet). Ein Zusammenhang könnte höchstens entstehen, wenn noch ein Cookie mitspielt. Das hat aber mit den GET-Parametern nichts zu tun.

    Ein weiterer Gedanke ist der, dass ich vielleicht etwas in der htaccess falsch eingestellt habe (Siehe Punkt 1), so dass der QueryString bei Reweiten abhanden kommt.

    Dann würde er aber ebenso beim Aufruf von Hand unter den Tisch fallen. Allerdings fehlt der Rewrite-Rule tatsächlich das QSA-Flag, mit dem der Query-String weitergeschleift wird. Das hättest du aber bei den Einzeltests vorab auch feststellen müssen.
    Anyway: Um Denkfehler im Rewriting auszuschließen, lass das erstmal weg und binde das Script über seinen echten Pfad ein. Wenn's dann klappt, wissen wir, dass wir beim Rewriting ansetzen müssen.

    So long,
     Martin

    --
    "Hier steht, deutsche Wissenschaftler hätten es im Experiment geschafft, die Lichtgeschwindigkeit auf wenige Zentimeter pro Sekunde zu verringern." - "Toll. Steht da auch, wie sie es gemacht haben?" - "Sie haben den Lichtstrahl durch eine Behörde geleitet."
    1. Hallo Martin,

      danke fuer deine Antwort.

      Zitat #1555 ;-)

      Hehe

      Ds Problem konnte ich nun beheben ;-)
      http://forum.de.selfhtml.org/?t=194035&m=1296743

      Aber eine Frage habe ich dann noch zu deinem Beitrag.

      [..] alle js-Anfragen automatisch auf ein bestimmtes Verzeichnis gemapped werden.
      Das heißt, eine eventuelle Verzeichnisangabe wird ignoriert. Hmm, der Sinn will mir nicht einleuchten. Aber wenn du meinst ...

      Es diente mir zu Vereinfachung. Das heisst, ich kann auf saemtliche Pfadangaben bei den Includes verzichten. Das ist das einzige Argument.
      Meinst du es hat entscheidende Nachteile (auszer das Ignorieren von Verzeichnisangaben) ?

      MfG
      Peter

      1. Hi Peter,

        Ds Problem konnte ich nun beheben ;-)
        http://forum.de.selfhtml.org/?t=194035&m=1296743

        habe ich gerade gelesen. Lag ich ja mit meinen Mutmaßungen auch nicht ganz falsch.

        Aber eine Frage habe ich dann noch zu deinem Beitrag.

        [...] alle js-Anfragen automatisch auf ein bestimmtes Verzeichnis gemapped werden.
        Das heißt, eine eventuelle Verzeichnisangabe wird ignoriert. Hmm, der Sinn will mir nicht einleuchten. Aber wenn du meinst ...
        Es diente mir zu Vereinfachung. Das heisst, ich kann auf saemtliche Pfadangaben bei den Includes verzichten. Das ist das einzige Argument.

        Ja, schon klar. Aber normalerweise bin ich durchaus bestrebt, durch die Organisation von Dateien (bzw. Ressourcen) in einer Verzeichnisstruktur eine gewisse Ordnung und Hierarchie abzubilden.
        Das heißt, die Verzeichnisnamen haben durchaus einen Sinn, und ich käme nicht auf die Idee, einen Mechanismus zu schaffen, die diese Struktur wieder wegzaubert.

        Meinst du es hat entscheidende Nachteile (auszer das Ignorieren von Verzeichnisangaben) ?

        Nicht sofort - aber ich sehe auch nicht den Vorteil. Ein Nachteil _könnte_ aufkommen, wenn du mal verschiedene Varianten einer Datei (Sprache?) parallel in verschiedenen Verzeichnissen vorhalten möchtest.
        Ergo: Solange du mit dieser Situation zurechtkommst, okay. Aber *ich* würde das nicht tun.

        Ciao,
         Martin

        --
        Zwischen Leber und Milz
        passt immer noch'n Pils.
        1. Hi Martin,

          [..]

          Irgendwo hast du ja recht. Habe mein htaccess nun entsprechend umgeschrieben und die Quellen angepasst. Sprich alles laeuft jetzt ueber eine vollstaendige Pfadangabe.

          Hierzu haette ich nochmal eine Frage.
          Und zwar wuerde ich folgenden Code sehr gerne vereinfachen/reduzieren.

          URLs mit dem String /switch/ werden als virtual_locations bearbeitet

          RewriteRule ^(en/switch).*$ RequestHandler.php?reqtype=virtual_location [QSA]
          RewriteRule ^(de/switch).*$ RequestHandler.php?reqtype=virtual_location [QSA]

          URLs die auf eine HTML-Datei verweisen

          RewriteRule (de/[^/]+.html)$ RequestHandler.php?reqtype=html [QSA]
          RewriteRule (en/[^/]+.html)$ RequestHandler.php?reqtype=html [QSA]

          Im Falle von http://example.org/en muss die Index-Datei aufgerufen werden

          RewriteRule ^(en/)$ RequestHandler.php?reqtype=index [QSA]
          RewriteRule ^(en)$ RequestHandler.php?reqtype=index [QSA]
          RewriteRule ^(de/)$ RequestHandler.php?reqtype=index [QSA]
          RewriteRule ^(de)$ RequestHandler.php?reqtype=index [QSA]

          Wie man sieht, ist das doppelt gemoppelt. Hintergrund ist der, dass ich nicht weisz, wie ich en und de zusammenfassen kann - ich dachte das waere in etwa so etwas wie ([de|en]). Aber das funktioniert nicht.
          Des weiteren habe ich Probleme damit Resourcen, die sich lediglich durch einen Slash am Ende unterscheiden, identisch zu behandeln.

          Kennst du hier schickere Moeglichkeiten?

          Danke & MfG
          Peter

          1. Hallo,

            Hierzu haette ich nochmal eine Frage.
            Und zwar wuerde ich folgenden Code sehr gerne vereinfachen/reduzieren.

            das bietet sich an. ;-)

            URLs mit dem String /switch/ werden als virtual_locations bearbeitet

            RewriteRule ^(en/switch).*$ RequestHandler.php?reqtype=virtual_location [QSA]
            RewriteRule ^(de/switch).*$ RequestHandler.php?reqtype=virtual_location [QSA]

            Wozu verwendest du hier die Klammern? Der Suchausdruck
              ^(en/switch).*$
            bedeutet doch, dass der geklammerte Inhalt gespeichert wird, so dass er im Ersetzungs-Ausdruck als $1, $2, ... wieder verwendet werden kann. Das nutzt du aber gar nicht, also sind die Klammern in deinem Fall ohne Bedeutung.

            Wie man sieht, ist das doppelt gemoppelt.

            Ja. Du kannst zwei Dinge vereinfachen.
            Erstens das Kürzel de oder en, das immer auftaucht:

            ich dachte das waere in etwa so etwas wie ([de|en])

            So ähnlich. Eckige Klammern bedeuten aber eine Zeichenklasse. Der Ausdruck [de|en] matcht also genau eines der in der Klammer stehenden Zeichen. Das ist nicht das, was du willst. Verwende stattdessen normale runde Klammern. In runden Klammern geht dann auch die alternative Angabe mehrerer Teilausdrücke mit dem | als ODER-Operator. Aus den beiden Zeilen

            RewriteRule ^(en/switch).*$ RequestHandler.php?reqtype=virtual_location [QSA]
            RewriteRule ^(de/switch).*$ RequestHandler.php?reqtype=virtual_location [QSA]

            wird dann nur noch eine:

            RewriteRule ^(en|de)/switch.*$ RequestHandler.php?reqtype=virtual_location [QSA]

            Wobei ich mich in diesem Beispiel frage, wo die Information bleibt, die das Sprachkürzel transportiert. Sie fällt unter den Tisch. In deinem Originalcode aber auch schon - oder wie wertest du diese Information aus?

            Des weiteren habe ich Probleme damit Resourcen, die sich lediglich durch einen Slash am Ende unterscheiden, identisch zu behandeln.

            Das ist das zweite, was du vereinfachen kannst. Ein Fragezeichen hinter einem Zeichen im RegEx bedeutet: Das Zeichen kann vorkommen, muss aber nicht. Somit lassen sich diese Zeilen

            RewriteRule ^(en/)$ RequestHandler.php?reqtype=index [QSA]
            RewriteRule ^(en)$ RequestHandler.php?reqtype=index [QSA]

            zu einer zusammenfassen:

            RewriteRule ^(en)/?$ RequestHandler.php?reqtype=index [QSA]

            Die Kombination der beiden Optimierungsmöglichkeiten bekommst du selbst hin ...

            So long,
             Martin

            --
            Solange der Nagellack nicht trocken ist,
            ist eine Frau praktisch wehrlos.
              (Burt Reynolds, US-Schauspieler)
            1. Hallo Martin,

              nochmal vielen Dank fuer deinen Beitrag. Nun habe ich ein Ergebnis, welches sich sehen lassen kann ;-)

              RewriteRule ^(de/switch).*$ RequestHandler.php?reqtype=virtual_location [QSA]
              Wozu verwendest du hier die Klammern? Der Suchausdruck

              Das ist eine gute Frage.

              RewriteRule ^(en|de)/switch.*$ RequestHandler.php?reqtype=virtual_location [QSA]

              Exakt.

              Wobei ich mich in diesem Beispiel frage, wo die Information bleibt, die das Sprachkürzel transportiert. Sie fällt unter den Tisch. In deinem Originalcode aber auch schon - oder wie wertest du diese Information aus?

              Das macht der RequestHandler. Eine switch-URL sieht zb aus wie folgt:
              http://example.org/en/switch/group/region/province/city/location
              Der RequestHandler zerlegt dann die einzelnen Parts der URL und gelangt somit auch an das Sprachkuerzel.

              RewriteRule ^(en)/?$ RequestHandler.php?reqtype=index [QSA]

              Klingt immer so einfach ;-)

              Die Kombination der beiden Optimierungsmöglichkeiten bekommst du selbst hin ...

              Ui, das hat mich Stunden gekostet ;-)

              Danke & MfG
              Peter

  3. Moin!

    Warum eigentlich diesen ganzen Bockstürze und Serverlast?

    Du gibst einfach eine .php-Datei als source an und lieferst den korrekten Mimetyp im Header aus:

    <script type="text/css" src="http://example.org/js/scriptgenerator.php?foo=bar" />

    header ('Content-type: text/javascript');
    und fertig ist der Ofen.

    Geht bei Bedarf auch für CSS:
    header ('Content-type: text/css');
    ... mit Grafiken:
    header ('Content-type: image/png');
    oder allem anderen möglichen Zeug wie z.B. Flash....

    MFFG (Mit freundlich- friedfertigem Grinsen)

    fastix

    --
    Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Seminare, Training, Development