web-dev-qa-db-fra.com

Quelles sont les recommandations pour la balise html <base>?

Je n'ai jamais vu balise HTML _<base>_ réellement utilisé nulle part auparavant. Y a-t-il des pièges à son utilisation qui signifient que je devrais l'éviter?

Le fait que je ne l'ai jamais remarqué en cours d'utilisation sur un site de production moderne (ou sur un autre site) me laisse perplexe, même s'il semble y avoir des applications utiles pour simplifier les liens sur mon site.


Modifier

Après avoir utilisé la balise de base pendant quelques semaines, j'ai fini par trouver quelques pièges majeurs avec l'utilisation de la balise de base, ce qui la rend beaucoup moins souhaitable qu'au départ. apparu. Les modifications apportées à _href='#topic'_ et _href=''_ sous la balise de base sont très incompatibles avec leur comportement par défaut, et cette modification du comportement par défaut pourrait facilement rendre Les bibliothèques tierces en dehors de votre contrôle sont très peu fiables de manière inattendue, car elles dépendent logiquement du comportement par défaut. Souvent, les modifications sont subtiles et posent des problèmes évidents lorsque l’on traite avec une base de code volumineuse. J'ai depuis créé une réponse détaillant les problèmes que j'ai rencontrés ci-dessous. Alors testez vous-même les résultats des liens avant de vous engager dans un déploiement généralisé de _<base>_, est mon nouveau conseil!

448
Kzqai

Ventilation des effets de la balise de base:

La balise de base semble avoir des effets non intuitifs, et je vous recommande de prendre connaissance des résultats et de les tester vous-même avant de vous fier à <base>! Depuis que je les ai découverts après en essayant d'utiliser la balise de base pour gérer des sites locaux avec des URL différentes et que je n'ai découvert les effets problématiques qu'après, à mon grand désarroi, je me suis senti obligé de créer ce résumé de ces pièges potentiels pour les autres.

Je vais utiliser une balise de base de: <base href="http://www.example.com/other-subdirectory/"> comme exemple dans les cas suivants, et je ferai semblant que la page sur laquelle se trouve le code est http://localsite.com/original-subdirectory

Majeur:

Aucun lien, ancre nommée ou href vierge ne pointe vers le sous-répertoire d'origine, à moins que cela ne soit explicitement expliqué: La balise de base crée tout ce qui est lié différemment, y compris same- L'ancre de page est liée à l'URL de la balise de base, par exemple:

  • <a href='#top-of-page' title='Some title'>A link to the top of the page via a named anchor</a>
    devient
    <a href='http://www.example.com/other-subdirectory/#top-of-page' title='Some title'>A link to an #named-anchor on the completely different base page</a>

  • <a href='?update=1' title='Some title'>A link to this page</a>
    devient
    <a href='http://www.example.com/other-subdirectory/?update=1' title='Some title'>A link to the base tag's page instead</a>

Avec certains travaux, vous pouvez résoudre ces problèmes sur les liens sur lesquels vous avez le contrôle, en spécifiant explicitement que ces liens renvoient à la page sur laquelle ils se trouvent, mais lorsque vous ajoutez des bibliothèques tierces au mélange qui reposent sur le comportement standard, cela peut facilement causer un grand désordre.

Mineur:

Correctif IE6 nécessitant des commentaires conditionnels: Requiert des commentaires conditionnels pour ie6 afin d'éviter de gâcher la hiérarchie des doms, c'est-à-dire <base href="http://www.example.com/"><!--[if lte IE 6]></base><![endif]--> comme BalusC mentionne dans sa réponse ci-dessus.

Donc dans l’ensemble, le problème majeur rend l’utilisation délicate à moins que vous ne maîtrisiez totalement l’édition de chaque lien, et comme je le craignais au départ, cela en fait plus que de gêner. Maintenant, je dois partir et réécrire toutes mes utilisations! : p

Liens associés aux tests de problèmes lors de l'utilisation de "fragments"/hashes:

http://www.w3.org/People/mimasa/test/base/

http://www.w3.org/People/mimasa/test/base/results


Edit by Izzy: Pour vous tous, rencontrez la même confusion que moi en ce qui concerne les commentaires:

Je viens de le tester moi-même, avec les résultats suivants:

  • le slash final ou non, ne fait aucune différence avec les exemples donnés ici (#anchor et ?query seraient simplement ajoutés au <BASE> spécifié).
  • Cela fait toutefois une différence pour les liens relatifs: en omettant la barre oblique finale, other.html et dir/other.html commenceraient au DOCUMENT_ROOT avec l'exemple donné, /other-subdirectory étant (correctement) traité comme fichier et donc omis.

Donc, pour les liens relatifs, BASE fonctionne bien avec la page déplacée - alors que les ancres et ?queries nécessitent que le nom du fichier soit spécifié explicitement (avec BASE ayant une barre oblique finale, ou le dernier élément non correspondant au nom du fichier dans lequel il est utilisé).

Pensez-y comme <BASE> remplaçant l'URL complète du fichier lui-même (et non le répertoire dans lequel il se trouve) , et vous aurez les choses bien. En supposant que le fichier utilisé dans cet exemple était other-subdirectory/test.html (après avoir été déplacé vers le nouvel emplacement), la spécification correcte aurait dû être:

<base href="http://www.example.com/other-subdirectory/test.html ">

- et voila, tout fonctionne comme prévu: #anchor, ?query, other.html, very/other.html, /completely/other.html .

156
Kzqai

Avant de décider d'utiliser ou non la balise <base>, vous devez comprendre comment elle fonctionne, à quoi elle sert, quelles en sont les implications et finalement l'emporter sur les avantages/inconvénients.


La balise <base> facilite principalement la création de liens relatifs dans des langages de modèles, car vous n'avez pas à vous soucier du contexte actuel dans tous les liens .

Vous pouvez faire par exemple

<base href="${Host}/${context}/${language}/">
...
<link rel="stylesheet" href="css/style.css" />
<script src="js/script.js"></script>
...
<a href="home">home</a>
<a href="faq">faq</a>
<a href="contact">contact</a>
...
<img src="img/logo.png" />

au lieu de

<link rel="stylesheet" href="/${context}/${language}/css/style.css" />
<script src="/${context}/${language}/js/script.js"></script>
...
<a href="/${context}/${language}/home">home</a>
<a href="/${context}/${language}/faq">faq</a>
<a href="/${context}/${language}/contact">contact</a>
...
<img src="/${context}/${language}/img/logo.png" />

Veuillez noter que la valeur <base href> se termine par une barre oblique, sinon elle sera interprétée par rapport au dernier chemin.


En ce qui concerne la compatibilité du navigateur, cela ne cause que des problèmes dans IE. La balise <base> est spécifiée en HTML comme et non avec une balise de fin </base>, il est donc légitime d'utiliser <base> sans balise de fin. . Cependant IE6 pense le contraire et tout le contenu après la balise <base> est dans ce cas placé comme enfant de l'élément <base> dans l'arborescence DOM HTML. Cela peut poser à première vue des problèmes inexplicables dans Javascript/jQuery/CSS, c’est-à-dire que les éléments sont complètement inaccessibles dans des sélecteurs spécifiques comme html>body, jusqu’à ce que vous découvriez dans l’inspecteur HTML DOM qu’il devrait y avoir un base ( et head) entre les deux.

Un correctif IE6 commun utilise un commentaire conditionnel IE pour inclure la balise de fin:

<base href="http://example.com/en/"><!--[if lte IE 6]></base><![endif]-->

Si vous ne vous souciez pas du validateur W3, ou si vous utilisez déjà HTML5, vous pouvez simplement le fermer automatiquement, chaque navigateur Web le supporte de toute façon:

<base href="http://example.com/en/" />

La fermeture de la balise <base> corrige également instantanément insanity de IE6 sur WinXP SP3 de demander à <script> des ressources avec un URI relatif dans src dans une boucle infinie.

Un autre problème potentiel IE se manifestera lorsque vous utiliserez un URI relatif dans la balise <base>, tel que <base href="//example.com/somefolder/"> ou <base href="/somefolder/">. Cela échouera dans IE6/7/8. Ce n'est cependant pas exactement la faute du navigateur; L'utilisation des adresses URI relatives dans la balise <base> est en soi erronée. La spécification HTML4 indiquait qu'il devait s'agir d'un URI absolu, en commençant par le schéma http:// ou https://. Cela a été déposé dans spécification HTML5 . Donc, si vous utilisez uniquement les navigateurs compatibles HTML5 et cible HTML5, tout devrait bien se passer en utilisant un URI relatif dans la balise <base>.


En ce qui concerne l'utilisation d'ancres de fragments de nom/hachage telles que <a href="#anchor">, interrogez des ancres de chaînes de caractères telles que <a href="?foo=bar"> et des ancres de fragments de chemin d'accès telles que <a href=";foo=bar">, avec la balise <base> que vous déclarez fondamentalement tous les liens relatifs , , y compris ce type d'ancrage. Aucun des liens relatifs n'est plus relatif à l'URI de la demande actuelle (comme ce serait le cas sans la balise <base>). Cela peut en premier lieu être source de confusion pour les débutants. Pour construire ces ancres de la bonne façon, vous devez inclure l’URI,

<a href="${uri}#anchor">hash fragment</a>
<a href="${uri}?foo=bar">query string</a>
<a href="${uri};foo=bar">path fragment</a>

${uri} se traduit essentiellement par $_SERVER['REQUEST_URI'] en PHP, ${pageContext.request.requestURI} en JSP et #{request.requestURI} en JSF. Il convient de noter que les frameworks MVC tels que JSF ont des balises réduisant tout ce passe-partout et éliminant le besoin de <base>. Voir aussi a.o. Quelle URL utiliser pour lier/naviguer vers d'autres pages JSF .

252
BalusC

Eh bien, attendez une minute. Je ne pense pas que la balise de base mérite cette mauvaise réputation.

La bonne chose à propos de la balise de base est qu’elle vous permet de réécrire des URL complexes avec moins de tracas.

Voici un exemple. Vous décidez de déplacer http://example.com/product/category/thisproduct vers http://example.com/product/thisproduct . Vous modifiez votre fichier .htaccess pour réécrire la première URL sur la deuxième URL.

Avec la balise de base en place, vous effectuez votre réécriture .htaccess et le tour est joué. Aucun problème. Mais sans la balise de base, tous vos liens relatifs se briseront.

Les réécritures d'URL sont souvent nécessaires, car leur modification peut aider l'architecture de votre site et la visibilité du moteur de recherche. Certes, vous aurez besoin de solutions de contournement pour les problèmes "#" et "" mentionnés par les gens. Mais la balise de base mérite une place dans la boîte à outils.

26
Summer

Pour décider s’il doit être utilisé ou non, vous devez savoir ce qu’il fait et s’il est nécessaire. Ceci est déjà partiellement décrit dans cette réponse , à laquelle j'ai également contribué. Mais pour le rendre plus facile à comprendre et à suivre, une seconde explication ici. Nous devons d'abord comprendre:

Comment les liens sont-ils traités par le navigateur sans que <BASE> soit utilisé?

Pour quelques exemples, supposons que nous avons ces URL:

A) http://www.example.com/index.html
B) http://www.example.com/
C) http://www.example.com/page.html
D) http://www.example.com/subdir/page.html

A + B aboutissent tous deux au même fichier (index.html) au navigateur, C envoie bien sûr page.html et D envoie /subdir/page.html.

Supposons en outre que les deux pages contiennent un ensemble de liens:

1) liens absolus pleinement qualifiés (http://www...)
2) liens absolus locaux (/some/dir/page.html)
3) liens relatifs, y compris les noms de fichier (dir/page.html), et
4) liens relatifs avec "segments" uniquement (#anchor, ?foo=bar).

Le navigateur reçoit la page et rend le code HTML. S'il trouve une URL, il doit savoir où l'indiquer. C'est toujours clair pour Link 1), qui est pris tel quel. Tous les autres dépendent de l'URL de la page rendue:

URL     | Link | Result
--------+------+--------------------------
A,B,C,D |    2 | http://www.example.com/some/dir/page.html
A,B,C   |    3 | http://www.example.com/dir/page.html
D       |    3 | http://www.example.com/subdir/dir/page.html
A       |    4 | http://www.example.com/index.html#anchor
B       |    4 | http://www.example.com/#anchor
C       |    4 | http://www.example.com/page.html#anchor
D       |    4 | http://www.example.com/subdir/page.html#anchor

Maintenant qu'est-ce qui change avec<BASE> utilisé?

<BASE> est supposé remplacer l'URL tel qu'il apparaît au navigateur. Ainsi, tous les liens sont rendus comme si l'utilisateur avait appelé l'URL spécifiée dans <BASE>. Ce qui explique en partie la confusion dans plusieurs des autres réponses:

  • encore une fois, rien ne change pour les "liens absolus pleinement qualifiés" ("type 1")
  • pour les liens absolus locaux, le serveur ciblé peut changer (si celui spécifié dans <BASE> diffère de celui appelé initialement par l'utilisateur)
  • les URL relatives deviennent critiques ici, vous devez donc faire très attention à la manière dont vous définissez <BASE>:
    • il vaut mieux éviter de le configurer sur un répertoire. Ce faisant, les liens de "type 3" peuvent continuer à fonctionner, mais ils cassent très certainement ceux de "type 4" (sauf pour "cas B")
    • réglez-le sur le nom de fichier qualifié complet ​​produit, dans la plupart des cas, les résultats souhaités.

Un exemple explique le mieux

Supposons que vous vouliez "embellir" une URL en utilisant mod_rewrite:

  • fichier réel: <DOCUMENT_ROOT>/some/dir/file.php?lang=en
  • uRL réelle: http://www.example.com/some/dir/file.php?lang=en
  • uRL conviviale: http://www.example.com/en/file

Supposons que mod_rewrite soit utilisé pour de manière transparente réécrire l'URL conviviale sur l'URL réelle (pas de réorientation externe, de sorte que celui "convivial" reste dans la barre d'adresse du navigateur, tandis que le réel est chargé). Que faire maintenant?

  • no <BASE> spécifié: coupe tous les liens relatifs (car ils seraient basés sur http://www.example.com/en/file maintenant)
  • <BASE HREF='http://www.example.com/some/dir>: Absolument faux. dir serait considéré comme la partie fichier de l'URL spécifiée. Par conséquent, tous les liens relatifs sont rompus.
  • <BASE HREF='http://www.example.com/some/dir/>: C'est déjà mieux. Mais les liens relatifs de "type 4" sont toujours cassés (sauf pour "cas B").
  • <BASE HREF='http://www.example.com/some/dir/file.php>: Exactement. Tout devrait fonctionner avec celui-ci.

Une dernière note

N'oubliez pas que cela s'applique à toutes les URL de votre document:

  • <A HREF=
  • <IMG SRC=
  • <SCRIPT SRC=
19
Izzy

Drupal s'est initialement appuyé sur la balise <base>, puis a pris la décision de ne pas l'utiliser en raison de problèmes liés aux robots d'exploration et aux caches HTTP.

Je n'aime généralement pas poster des liens. Mais celui-ci vaut vraiment la peine d'être partagé car il pourrait profiter à ceux qui recherchent les détails d'une expérience réelle avec le tag <base>:

http://drupal.org/node/13148

12
Amr Mostafa

Cela facilite la consultation des pages pour une consultation hors ligne; vous pouvez placer l'URL qualifiée complète dans la balise de base pour que vos ressources distantes se chargent correctement.

10
Erik

Le hash "#" fonctionne actuellement pour les liens de saut en conjonction avec l'élément de base, mais uniquement dans les dernières versions de Google Chrome et de Firefox, PAS IE9.

IE9 semble provoquer le rechargement de la page, sans sauter n'importe où. Si vous utilisez des liens de saut à l'extérieur d'une iframe, tout en demandant au cadre de charger les liens de saut sur une page distincte du cadre, vous obtiendrez une deuxième copie de la page de lien de saut chargée à l'intérieur du cadre.

5
Tristan

Ce n'est probablement pas très populaire parce que ce n'est pas bien connu. Je n'aurais pas peur de l'utiliser car tous les principaux navigateurs le supportent.

Si votre site utilise AJAX, vous devez vous assurer que toutes vos pages sont correctement configurées ou vous risquez de vous retrouver avec des liens qui ne peuvent pas être résolus.

N'utilisez simplement pas l'attribut target dans une page HTML 4.01 Strict.

5
Ben S

Dans le cas des images SVG insérées dans la page, un autre problème important se pose lorsque la balise base est utilisée:

Depuis avec la balise base (comme indiqué plus haut), vous perdez la possibilité d’utiliser des URL de hachage relatives comme dans

<a href="#foo">

car ils seront résolus avec l'URL de base plutôt qu'avec l'emplacement du document actuel et ne sont donc plus relatifs. Vous devrez donc ajouter le chemin du document actuel à ce type de liens, comme dans

<a href="/path/to/this/page/name.html#foo">

Ainsi, l'un des aspects apparemment positifs de la balise base (qui consiste à éloigner les préfixes d'URL longs de la balise d'ancrage et à obtenir des ancres plus agréables et plus courtes) se retourne complètement pour les URL de hachage locales.

Ceci est particulièrement gênant lorsque vous insérez du SVG dans votre page, qu'il s'agisse de SVG statique ou de SVG généré dynamiquement, car SVG peut contenir beaucoup de telles références et elles se briseront dès qu'une balise base sera utilisée , sur la plupart des implémentations d’agent utilisateur, mais pas toutes (au moins, Chrome fonctionne toujours dans ces scénarios au moment de la rédaction).

Si vous utilisez un système de templates ou une autre chaîne d'outils qui traite/génère vos pages, j'essayerais toujours de me débarrasser de la balise base, car, à mon avis, elle apporte plus de problèmes qu'elle n'en résout.

3
Sebastian

De plus, vous devez vous rappeler que si vous utilisez votre serveur Web sur un port non standard, vous devez également inclure le numéro de port sur la base href:

<base href="//localhost:1234" />  // from base url
<base href="../" />  // for one step above
3
Kirill Zotov

Je n'ai jamais vraiment vu un point en l'utilisant. Fournit très peu d'avantages et pourrait même rendre les choses plus difficiles à utiliser.

Sauf si vous avez des centaines ou des milliers de liens, tous dans le même sous-répertoire. Ensuite, vous pourriez économiser quelques octets de bande passante.

Après coup, il me semble me rappeler qu’il ya un problème avec l’étiquette dans IE6. Vous pouvez les placer n'importe où dans le corps, en redirigeant différentes parties du site vers différents emplacements. Cela a été corrigé dans IE7, qui cassait beaucoup de sites.

2
Atli

Travailler avec AngularJS, la balise BASE a cassé $ cookieStore en silence et il m'a fallu un certain temps pour comprendre pourquoi mon application ne pouvait plus écrire de cookies. Être averti...

2
johan

ont également un site où base-tag est utilisé, et le problème décrit est survenu. (après la mise à jour de jquery), a été capable de le réparer en ayant des URLs comme suit:

<li><a href="{$smarty.server.REQUEST_URI}#tab_1"></li>

cela les rend "local"

références que j'ai utilisées:

http://bugs.jqueryui.com/ticket/7822http://htmlhelp.com/reference/html40/head/base.htmlhttp: //tjvantoll.com/2013/02/17/using-jquery-ui-tabs-with-the-base-tag/

2
womd

J'ai trouvé un moyen d'utiliser <base> et des liens basés sur des ancres. Vous pouvez utiliser JavaScript pour que les liens tels que #contact fonctionnent comme ils le doivent. Je l'ai utilisé dans certaines pages de parallaxe et cela fonctionne pour moi.

<base href="http://www.mywebsite.com/templates/"><!--[if lte IE 6]></base><![endif]-->

...content...

<script>
var link='',pathname = window.location.href;
$('a').each(function(){
    link = $(this).attr('href');
    if(link[0]=="#"){
        $(this).attr('href', pathname + link);
    }
});
</script>

Vous devriez utiliser à la fin de la page

1
quakeglen

Une chose à garder à l'esprit:

Si vous développez une page Web à afficher dans UIWebView sur iOS, vous devez utiliser la balise BASE. Cela ne fonctionnera tout simplement pas autrement. Qu'il s'agisse de JavaScript, CSS ou d'images, aucune d'entre elles ne fonctionnera avec des liens relatifs sous UIWebView, à moins que la balise BASE soit spécifiée.

J'ai déjà été surpris par ça, jusqu'à ce que je le sache.

1
vitaly-t