CSS verdwijnt bij trailing slash (/) in URL

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Jan Kila

Jan Kila

11/02/2020 14:32:26
Quote Anchor link
Wanneer ik een trailing slash achter het URL plaats verdwijnt, oh raadsel, m'n CSS.
Ik krijg perfect de gewenste pagina, maar; ZONDER trailing slash MET CSS - en MET trailing slash ZONDER CSS.
Heeft iemand enig idee hoe dit gedrag is te voorkomen?

Waarom het gebeurt is me inmiddels wel duidelijk.
ZONDER trailing slash achter het URL blijkt uit het Netwerk overzicht dat de stylesheet style.css wordt aangeroepen als:
http:://localhost:3000/assets/css/style.css; dit beschouw ik als de normale aanroep.

MET trailing slash achter het URL geeft het Netwerk overzicht aan dat de stylesheet style.css aanroep is:
http:://localhost:3000/home/assets/css/style.css; en dat pad bestaat niet in de site - dus geen CSS.

Op zich begrijpelijk dat het niet werkt, maar hoe ontstaan deze twee verschillende aanroepen?
En - belangrijker - hoe kan ik dit vermijden?

O ja, de redirect in .htaccess luidt:
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]

Toevoeging op 11/02/2020 14:44:28:

Bijzonder, maar ook dit probleem heeft zich weer snel opgelost.
Ik heb de link naar het style sheet gewijzigd in:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
    <link rel="stylesheet" href="<?php echo BASE_URL. '/assets/css/style.css'; ?>" />

Even een helder moment na toch wel vrij lang sukkelen.
Dit lost het probleem op, maar ik wil ook graag weten hoe het ontstaan.
Iemand een verklaring?
Gewijzigd op 11/02/2020 14:45:31 door Jan Kila
 
PHP hulp

PHP hulp

10/08/2020 03:41:02
 
Thomas van den Heuvel

Thomas van den Heuvel

11/02/2020 16:06:10
Quote Anchor link
Kijk eens in de netwerktab van je browser (F12) en ververs dan je pagina. Dan zie je welke bestanden jouw browser probeert op te vragen die aan de webpagina hangen. Waarschijnlijk heb je in het <head> gedeelte van je pagina een relatieve verwijzingen staan naar je stylesheets.

Op het moment dat er slashes in je URL zitten zit je dus niet langer in de "root" van je webdirectory, maar één of meerdere niveaus lager. Het maakt daarbij niet uit of je rewriterules hebt die alles naar index.php sturen (dit is een server-aangelegenheid). De browser (client side) ziet "hee ik zit in het pad /news/whatever en ik heb een relatieve verwijzing naar /css/style.css, dus die zou dan in /news/css/style.css moeten zitten" (want /news is je huidige directory).

De browser heeft ook geen kennis van de technische oplossing aan de serverkant, alle "bestanden" die je opvraagt zijn in wezen "virtueel" maar jouw browser weet dat niet, noch is het de taak van de browser om dit te snappen, deze werkt gewoon met het HTTP(S) protocol en behandelt ze gewoon als fysieke bestanden en volgt de logica die ze altijd volgt, conform de protocollen die hiervoor gelden.

Het probleem ontstaat doordat deze relatieve verwijzingen geen vast uitgangspunt hebben. Omdat je deze niet expliciet opgeeft zal de huidige directory het uitgangspunt zijn, en die wordt dus aan het pad naar het CSS-bestand toegevoegd.

Dit kun je op meerdere manieren oplossen, bijvoorbeeld door:
- absolute verwijzingen (volledige URLs) te gebruiken
- een <base> tag toe te voegen in het <head> gedeelte, zodat er expliciet een vast uitgangspunt staat ingesteld

Heb je dit alles m.b.v. een tutorial gebouwd trouwens, want dit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]

is in principe niet verkeerd, maar de toevoeging ?url=$1 is compleet overbodig, en zorgt er ook voor dat je querystring ($_GET) wordt geïnjecteerd met onzichtbare waarden wat esthetisch gezien niet heel erg verantwoord is.

Het kan ook onvoorspelbare gevolgen hebben op het moment dat je deze "gereserveerde" variabele toevoegt aan een "nette url", dus bijvoorbeeld /news/whatever?url=woops. Wat gebeurt er dan?

Indien je geen specifieke reden hebt voor deze toevoeging dan zou ik dat deel ook verwijderen. Alle informatie (dus wat je ten overvloede nogmaals in $_GET['url'] stopt) is gewoon beschikbaar via $_SERVER['REQUEST_URI']. Vervolgens kun je hier standaard PHP-functies zoals parse_url() op loslaten om het "applicatiepad" te extraheren.

PS welkom in de wereld van relatieve en absolute paden. Op het moment dat je met rewriterules aan de slag gaat zul je hier nog veel plezier mee gaan krijgen :).
Gewijzigd op 11/02/2020 16:22:53 door Thomas van den Heuvel
 
Frank Nietbelangrijk

Frank Nietbelangrijk

11/02/2020 17:32:17
Quote Anchor link
Toch lijkt het me niet helemaal juist dat dat woordje 'home' dan in je pad komt te staan. Het lijkt mij dat je router dan de url interpreteert als de url naar je homepage? Wellicht zit daar dan dus nog een probleempje in. Achter welke URL heb je dan een slash? Is dat de enkel bij de URL http:://localhost:3000/ ? of ook bij een URL zoals http:://localhost:3000/andere-directory/ ?
 
Thomas van den Heuvel

Thomas van den Heuvel

11/02/2020 19:38:16
Quote Anchor link
Dat is mogelijk een dingetje, maar het heeft niet zoveel zin om een situatie te bestuderen waarvan je weet dat deze niet klopt :p. Verricht eerst de noodzakelijke aanpassingen om de (directe) fout(en) op te lossen, en kijk dan of het probleem nog speelt.

In dit geval zorgen beide voorgestelde oplossingen ervoor dat het wel of niet hebben van een slash aan het einde van de URL er niet toe doet dus dat is in zekere zin niet heel erg relevant.

Neemt niet weg dat je een goed uitgewerkt plan moet hebben over de manier waarop je navigatie intern en extern werkt, vooral als je met schone URLs / rewriterules / routers etc. werkt.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

11/02/2020 19:52:07
Quote Anchor link
Mja Thomas heeft wel gelijk.

Ik realiseer me nu dat de meeste frameworks ook enkel een URL wijzigen als het opgevraagde bestand (of directory) niet bestaat.

Een .htaccess bestand die dat in zich heeft zou er ongeveer zo uit zien:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
RewriteEngine On

# Alleen als het om een niet bestaand bestand gaat
RewriteCond %{REQUEST_FILENAME} !-f
# Alleen als het om een niet bestaande directory gaat
RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.+)$ index.php [QSA,L]
Gewijzigd op 11/02/2020 20:36:35 door Frank Nietbelangrijk
 
Thomas van den Heuvel

Thomas van den Heuvel

11/02/2020 20:24:02
Quote Anchor link
En dan zonder ?url=$1 :p
 
Frank Nietbelangrijk

Frank Nietbelangrijk

11/02/2020 20:35:55
Quote Anchor link
Thomas van den Heuvel op 11/02/2020 20:24:02:
En dan zonder ?url=$1 :p


En dat vergat ik natuurlijk :o

Toch maar even aangepast.
Gewijzigd op 11/02/2020 20:37:32 door Frank Nietbelangrijk
 
Jan Kila

Jan Kila

12/02/2020 15:32:38
Quote Anchor link
En ook zonder [QSA; een Query String Append blijkt ook niet nodig. Logisch trouwens want er is geen query string meer.
Het werkt prima met: $_SERVER['REQUEST_URI']. Parsen gaat op de manier zoals het al ging.
Met $_SERVER['REQUEST_URI'] zijn er minder handelingen; en minder handelingen betekent dat er minder fout kan gaan; en daar ben ik vóór!
Met jullie hulp werkt m'n MVC-framework(je); vanaf hier is het meer van hetzelfde. Het is trouwens wel heel veel werk om die crawler gelukkig te maken; heel leerzaam ook!
De database connectie was nog een dingetje, maar ook dat heb ik opgelost.


Toevoeging op 12/02/2020 15:52:06:

Toch nog even zeuren.
Bij gebruik van $route = $_SERVER['REQUEST_URI']; geeft een url a la: http://localhost:3000/story/single na:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$parts = explode('/', $route);

de volgende output:
route: /story/single
Array
(
[0] =>
[1] => story
[2] => single
)
1
Nu is het eerste element van het array leeg; en bij gebruik van $_GET['url'], lee s ik daar: [0] => story
Dat is even wennen.
Heb ik nu ook de garantie dat het eerste element ALTIJD leeg is, of is er nog een afhankelijkheid?
 
Thomas van den Heuvel

Thomas van den Heuvel

12/02/2020 16:26:04
Quote Anchor link
Trim gewoon alle leading en trailing slashes?

QSA zou ik gewoon laten staan. Misschien gebruik je het nu niet, maar dat komt mogelijk nog, bijvoorbeeld bij een soort van pagina-navigatie of zoekfunctionaliteit. Zou dat alles niet op voorhand uitsluiten.

Dus eigenlijk min of meer dit.
 
Jan Kila

Jan Kila

12/02/2020 16:29:27
Quote Anchor link
Met: ltrim($newRoute['path'], '/'); kom ik daar langs; en kan ik de rest van de code in stand houden.

Maar géén slash achter de site root (localhost:3000story) geeft wel een vreemd resultaat:
https://www.google.com/search?client=safari&rls=en&q=localhost:3000story&ie=UTF-8&oe=UTF-8

Dát zou ik wel willen afvangen.

Toevoeging op 12/02/2020 16:33:00:

RewriteBase /
Als ik je goed begrijp.
 
Thomas van den Heuvel

Thomas van den Heuvel

12/02/2020 16:54:05
Quote Anchor link
Erm. Je trimt de REQUEST_URI, zodat je enkel story/single overhoudt. Als je dat explode op "/" houd je twee elementen over: "story" (element op index 0) en "single" (element op index 1). Dat is wat je wilt neem ik aan? Geen lege elementen in het ge-explode array.

edit: als je gewoon je website-voorpagina aanroept is het array leeg, als dat het geval is dan pak je een default route/stuk code.

edit 2: maak ook onderscheid tussen:
#1 de URLs die jouw applicatie produceert
#2 de afhandeling van het opvragen van een specifieke URL

dit zijn twee verschillende dingen die op elkaar aan zouden moeten sluiten.
Gewijzigd op 12/02/2020 16:57:59 door Thomas van den Heuvel
 
Jan Kila

Jan Kila

12/02/2020 16:57:48
Quote Anchor link
Zo bedoelde ik het, dank je.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.