web-dev-qa-db-fra.com

Est-il valide de remplacer http: // par // dans un <script src = "http: // ...">?

J'ai l'élément suivant:

<script type="text/javascript" src="https://cdn.example.com/js_file.js"></script>

Dans ce cas, le site est HTTPS, mais le site peut également n'être que HTTP. (Le fichier JS se trouve sur un autre domaine.) Je me demande s'il est correct de procéder comme suit pour des raisons de commodité:

<script type="text/javascript" src="//cdn.example.com/js_file.js"></script>

Je me demande s'il est valide de supprimer le http: ou le https:?

Cela semble fonctionner partout où j'ai testé, mais y a-t-il des cas où cela ne fonctionne pas?

448
Darryl Hein

Une URL relative sans schéma (http: ou https :) est valide, par RFC 3986: "Identificateur de ressource uniforme (URI): syntaxe générique", Section 4.2 . Si un client s'étouffe dessus, c'est que c'est sa faute qui ne respecte pas la syntaxe d'URI spécifiée dans le RFC.

Votre exemple est valide et devrait fonctionner. J'ai moi-même utilisé cette méthode d'URL relative sur des sites à trafic intense et aucune plainte n'a été reçue. Nous testons également nos sites sous Firefox, Safari, IE6, IE7 et Opera. Ces navigateurs comprennent tous ce format d'URL.

379
Jeff

Il est garanti qu’il fonctionnera dans n’importe quel navigateur classique (je ne prends pas en considération les navigateurs dont la part de marché est inférieure à 0,05%). Heck, cela fonctionne dans Internet Explorer 3.0.

RFC 3986 définit un URI composé des parties suivantes:

     foo://example.com:8042/over/there?name=ferret#nose
     \_/   \______________/\_________/ \_________/ \__/
      |           |            |            |        |
   scheme     authority       path        query   fragment

Lorsque vous définissez des URI relatifs ( Section 5.2 ), vous pouvez omettre n’importe laquelle de ces sections, en commençant toujours par la gauche. En pseudo-code, cela ressemble à ceci:

 result = ""

  if defined(scheme) then
     append scheme to result;
     append ":" to result;
  endif;

  if defined(authority) then
     append "//" to result;
     append authority to result;
  endif;

  append path to result;

  if defined(query) then
     append "?" to result;
     append query to result;
  endif;

  if defined(fragment) then
     append "#" to result;
     append fragment to result;
  endif;

  return result;

L'URI que vous décrivez est un URI relatif sans schéma.

149
Andrew Moore

y a-t-il des cas où cela ne fonctionne pas?

Si la page parent a été chargée à partir de file://, alors cela ne fonctionnera probablement pas (il essaiera d’obtenir file://cdn.example.com/js_file.js, ce que vous pourriez bien entendu fournir également localement).

77
Thilo

Beaucoup de gens appellent cela une URL relative au protocole.

Il en résulte un double téléchargement de fichiers CSS dans IE 7 & 8 .

40
SLaks

Ici, je duplique la réponse dans Fonctionnalités cachées de HTML :

Utilisation d'un absolu indépendant du protocole chemin:

<img src="//domain.com/img/logo.png"/>

Si le navigateur visualise une page dans SSL via HTTPS, alors il va demander cet actif avec le protocole https, sinon, il sera demandé avec HTTP.

Cela évite que le message d'erreur «Cette page Contient à la fois des éléments sécurisés et non sécurisés » Dans IE, en conservant toutes vos demandes d'actifs dans le même protocole.

Avertissement: lorsqu'il est utilisé sur un <link> ou un @import pour une feuille de style, IE7 et IE8 téléchargez le fichier deux fois . Tous les autres les utilisations, cependant, sont très bien.

23
kennytm

Il est parfaitement valable de laisser le protocole. La spécification d'URL est très claire à ce sujet depuis des années et je n'ai pas encore trouvé de navigateur qui ne le comprend pas. Je ne sais pas pourquoi cette technique n'est pas mieux connue; c'est la solution idéale au problème épineux du franchissement des frontières HTTP/HTTPS. Plus ici: Transitions Http-https et URL relatives

16
Ned Batchelder

y a-t-il des cas où cela ne fonctionne pas?

Juste pour ajouter ceci, si vous développez sur un serveur local, cela pourrait ne pas fonctionner. Vous devez spécifier un schéma, sinon le navigateur peut supposer que src="//cdn.example.com/js_file.js" est src="file://cdn.example.com/js_file.js", ce qui se produira, car vous n'hébergez pas cette ressource localement.

Microsoft Internet Explorer semble être particulièrement sensible à cela, voyez cette question: Impossible de charger jQuery dans Internet Explorer sur localhost (WAMP)

Vous essaierez probablement toujours de trouver une solution qui fonctionne sur tous vos environnements avec le moins de modifications nécessaires.

La solution utilisée par HTML5Boilerplate consiste à appliquer un repli lorsque la ressource n'est pas chargée correctement, mais cela ne fonctionne que si vous incorporez une vérification:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<!-- If jQuery is not defined, something went wrong and we'll load the local file -->
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.10.2.min.js"><\/script>')</script>

UPDATE: HTML5Boilerplate utilise maintenant <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js après avoir décidé de désapprouver les URL relatives au protocole, voir [ici] [3].

5
bg17aw

Après la référence du gnud, le RFC 3986, section 5.2 dit:

Si le composant de schéma est défini, cela indique que la référence commence par un nom de schéma, la référence est alors interprétée comme un URI absolue et nous avons terminé. Sinon, le schéma de l'URI de référence est hérité du composant de schéma de l'URI de base.

Donc, // est correct :-)

3
Pablo Torrecilla

Nous constatons 404 erreurs dans nos journaux lorsque nous utilisons //somedomain.com comme références à des fichiers JS. 

Les références à l'origine des 404 se présentent comme suit: Ref:

<script src="//somedomain.com/somescript.js" />

404 demande:

http://mydomain.com//somedomain.com/somescript.js

Avec ceux-ci apparaissant régulièrement dans les journaux de notre serveur Web, il est prudent de dire que: Tous les navigateurs et les bots NE PAS honorer la section 4.2 de la RFC 3986. Le pari le plus sûr est d'inclure le protocole autant que possible.

2
Lemiarty

Oui, ceci est documenté dans RFC 3986 , section 5.2:

(edit: Oups, ma référence RFC était obsolète).

2
gnud

C'est en effet correct, comme d'autres réponses l'ont indiqué. Vous devez cependant noter que certains robots Web vont définir 404 en les demandant sur votre serveur comme s'il s'agissait d'une URL locale. (Ils ignorent la double barre oblique et la traitent comme une seule barre oblique).

Vous voudrez peut-être configurer une règle sur votre serveur Web pour les récupérer et les rediriger.

Par exemple, avec Nginx, vous ajouteriez quelque chose comme:

location ~* /(?<redirect_domain>((([a-z]|[0-9]|\-)+)\.)+([a-z])+)/(?<redirect_path>.*) {
  return 301 $scheme:/$redirect_domain/$redirect_path;
}

Notez cependant que si vous utilisez des points dans vos URI, vous devrez augmenter la spécificité, sinon les pages seront redirigées vers des domaines inexistants.

En outre, il s’agit d’une expression rationnelle assez volumineuse à exécuter pour chaque requête - à mon avis, cela vaut la peine de punir les navigateurs non conformes avec 404s sur une performance (légère) de la plupart des navigateurs compatibles.

2
jlovison

Le modèle que je vois sur html5-boilerplate est:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.10.2.min.js"><\/script>')</script>

Il fonctionne sans problème sur différents systèmes comme http, https, file.

1
neurite

Comme votre exemple est une liaison à un domaine externe, si vous utilisez HTTPS, vous devez vérifier que le domaine externe est également configuré pour SSL. Sinon, vos utilisateurs risquent de rencontrer des erreurs SSL et/ou 404 (par exemple, les anciennes versions de Plesk Store HTTP et HTTPS dans des dossiers distincts). Pour les CDN, cela ne devrait pas être un problème, mais pour tout autre site Web, ce pourrait être le cas.

Sur une note de côté, testé tout en mettant à jour un ancien site Web et fonctionne également dans l'URL = partie d'un META REFRESH.

0
user2246924