URL relative à un numéro de port différent dans un lien hypertexte?

136

Existe-t-il un moyen sans Javascript / script côté serveur de se lier à un numéro de port différent sur la même boîte, si je ne connais pas le nom d'hôte?

par exemple:

<a href=":8080">Look at the other port</a>

(Cet exemple ne fonctionne pas car il traitera simplement: 8080 comme une chaîne vers laquelle je souhaite accéder)

Ciaran McNulty
la source
stackoverflow.com/questions/8317059/relative-path-but-for-port Vérifiez ceci ... cela a fonctionné pour moi
Parce que beaucoup de gens ci-dessous s'entassent avec des solutions côté serveur, le $http_hostvar NGINX fonctionne, par exemple: return 200 '<html><body><iframe id="ic" src="http://$http_host:2812/"></iframe></body></html>c'est-à-dire dans un /etc/nginx/conf.d/strange.conffichier.
MarkHu

Réponses:

52

Ce serait bien si cela pouvait fonctionner, et je ne vois pas pourquoi car il :s'agit d'un caractère réservé pour la séparation des ports à l'intérieur du composant URI, de sorte que le navigateur pourrait interpréter cela de manière réaliste comme un port par rapport à cette URL, mais malheureusement, ce n'est pas le cas. t et il n'y a aucun moyen pour cela de le faire.

Vous aurez donc besoin de Javascript pour cela;

// delegate event for performance, and save attaching a million events to each anchor
document.addEventListener('click', function(event) {
  var target = event.target;
  if (target.tagName.toLowerCase() == 'a')
  {
      var port = target.getAttribute('href').match(/^:(\d+)(.*)/);
      if (port)
      {
         target.href = window.location.origin;
         target.port = port[1];
      }
  }
}, false);

Testé dans Firefox 4

Violon: http://jsfiddle.net/JtF39/79/


Mise à jour : Bug corrigé pour l'ajout du port à la fin de l'url et également ajouté la prise en charge des URL relatives et absolues à ajouter à la fin:

<a href=":8080/test/blah">Test absolute</a>
<a href=":7051./test/blah">Test relative</a>
Gary Green
la source
1
donc sans javascript il n'y a pas de vraie solution
Daniel Ruf
2
Il n'y a aucun moyen de faire cela sans Javascript.
Gary Green
6
Cela n'a pas fonctionné dans Safari 6. Le problème est que vous ne supprimez pas le port de l'URL relative, vous vous retrouvez donc avec quelque chose comme http://myhost:8080/:8080pour href=":8080". Vous pouvez ajouter cette ligne sous `target.port = port [1];` pour résoudre ce problème. target.href = target.href.replace("/:"+target.port, "");(Ce n'est pas une solution parfaite, car c'est une recherche / remplacement, mais c'est bon pour les cas simples où vous n'êtes pas inquiet de la présence de la chaîne de port dans l'URL.)
zekel
1
Ma solution était de créer une classe ASP.NET qui génère l'URL. C'est essentiellement la même solution que ci-dessus, juste côté serveur.
rookie1024
7
Veuillez ne pas utiliser cette solution . Il cassera complètement sur les clients sans Javascript, y compris probablement de nombreux appareils d'accessibilité comme les lecteurs d'écran. Générez plutôt les URL côté serveur.
Sven Slootweg
88

Que penses-tu de ceux-ci:

Modifiez le numéro de port au clic:

<a href="/other/" onclick="javascript:event.target.port=8080">Look at another port</a>

Cependant, si vous passez votre souris sur le lien, il n'affiche pas le lien avec le nouveau numéro de port inclus. Ce n'est que lorsque vous cliquez dessus qu'il ajoute le numéro de port. De plus, si l'utilisateur clique avec le bouton droit sur le lien et fait "Copier l'emplacement du lien", il obtient l'URL non modifiée sans le numéro de port. Ce n'est donc pas idéal.

Voici une méthode pour modifier l'URL juste après le chargement de la page, donc en survolant le lien ou en faisant "Copier l'emplacement du lien", vous obtiendrez l'URL mise à jour avec le numéro de port:

<html>
<head>
<script>
function setHref() {
document.getElementById('modify-me').href = window.location.protocol + "//" + window.location.hostname + ":8080/other/";
}
</script>
</head>

<body onload="setHref()">
<a href="/other/" id="modify-me">Look at another port</a>
</body>
</html>
Craig McQueen
la source
Merci d'avoir signalé les mises en garde dont j'étais au courant. Dans ma situation, les mises en garde ne sont pas très importantes et je préfère la simplicité de votre première solution. J'étais presque certain d'avoir déjà voté pour votre réponse, mais le logiciel semble ne pas le penser, et probablement la mémoire du logiciel est plus fiable que la mienne. Je l'ai voté (encore une fois ??).
Kevin Walker
J'ai résolu le mystère: j'ai accidentellement voté pour l'une des autres réponses à la place. Oups. Je n'ai pas assez de réputation pour annuler mon vote positif accidentel.
Kevin Walker du
<a href="#" onclick="javascript:event.target.port=8888">port 8888</a>devrait techniquement ne pas fonctionner, selon les spécifications de w3 . event.targetest censé être readonly. Mais cela semble fonctionner pour moi dans Chrome et Firefox!
JamesThomasMoon1979
Une solution de doublure est géniale! +1
Piotr Kula
Merci. J'aime votre deuxième solution car je peux définir le href de l'élément dans le HTML comme solution de secours à l'URI le plus probable.
Duncan X Simpson
56

Vous pouvez le faire facilement en utilisant document.write et l'URL s'affichera correctement lorsque vous le survolerez. Vous n'avez pas non plus besoin d'un identifiant unique en utilisant cette méthode et cela fonctionne avec Chrome, FireFox et IE. Étant donné que nous référençons uniquement des variables et ne chargeons aucun script externe, l'utilisation de document.write ici n'aura pas d'incidence sur les performances de chargement de la page.

<script language="JavaScript">
document.write('<a href="' + window.location.protocol + '//' + window.location.hostname + ':8080' + window.location.pathname + '" >Link to same page on port 8080:</a> ' );
</script>
Kurt Schultz
la source
3
Simple et élégant! Je ne sais pas pourquoi il n'y a pas plus de votes - c'est peut-être juste un retardataire.
Kevin
5
A noter également, vous n'avez pas besoin d'inclure une window.location.protocolpartie, tout en commençant par '//'.
kbrock
Semble légitime. Élégant.
Jay
Vraiment pratique et élégant.
Robert Lucian Chiriac
Juste pour dire que document.writec'est à peu près universellement déconseillé de nos jours. Il serait préférable de faire quelque chose commemyElement.innerHTML = '...'
mwfearnley
13

Modifiez le numéro de port au survol de la souris:

<a href="/other/" onmouseover="javascript:event.target.port=8080">Look at another port</a>

Il s'agit d'une amélioration de https://stackoverflow.com/a/13522508/1497139 qui n'a pas l'inconvénient de ne pas afficher le lien correctement.

Wolfgang Fahl
la source
5

Sans JavaScript, vous devrez vous fier à certains scripts côté serveur. Par exemple, si vous utilisez ASP, quelque chose comme ...

<a href="<%=Request.ServerVariables("SERVER_NAME")%>:8080">Look at the other port</a>

devrait marcher. Cependant, le format exact dépendra de la technologie que vous utilisez.

gdt
la source
4

Après avoir lutté avec cela, j'ai trouvé en fait que SERVER_NAME est une variable réservée. Donc, si vous êtes sur la page (www.example.com:8080), vous devriez pouvoir supprimer le 8080 et invoquer un autre port. Par exemple, ce code modifié a fonctionné pour moi et me déplace de n'importe quel port de base vers le port 8069 (remplacez votre port si nécessaire)

<div>
    <a href="http://<?php print
    $_SERVER{'SERVER_NAME'}; ?>:8069"><img
    src="images/example.png"/>Example Base (http)</a>
</div>
Landis Arnold
la source
1
Belle solution PHP! Vous pouvez omettre le protocole pour qu'il soit détecté automatiquement:<a href="https://<?php print $_SERVER{'SERVER_NAME'}; ?>:8069">
ADTC
3

Il est préférable d'obtenir l'URL des variables du serveur:

// PHP:
<a href="<?=$_SERVER['SERVER_NAME']?>:8080/index.php">

// ASP.net
<a href='<%=Request.ServerVariables("SERVER_NAME")%>:8080/index.asp'>
T30
la source
2

Pas besoin de javascript compliqué: insérez simplement un nœud de script après votre ancre, puis récupérez le nœud en javascript, et modifiez sa propriété href avec la méthode window.location.origin .

 <a id="trans">Look at the other port</a>
 <script>
      document.getElementById('trans').href='http://'+window.location.origin+':8081';
 </script>

La propriété id doit être unique à l'échelle de la page, vous pouvez donc utiliser une autre méthode pour récupérer les objets de nœud.

Testé avec apache et Firefox sous Linux.

MUY Belgique
la source
Pour une raison quelconque, cela n'a pas tout à fait fonctionné pour moi - cela a dirigé le navigateur vers http//localhost:8081, notez les deux points manquants. Je viens de supprimer complètement la partie protocole puisque Chrome a de toute façon assumé http.
joerick
Comment l'avez-vous testé?
MUY Belgium
1
Je pense que cela devrait être à la window.location.hostnameplace. Voir developer.mozilla.org/en-US/docs/Web/API/Location
mwfearnley
2

Cette solution me paraît plus propre

<a href="#"  
    onclick="window.open(`${window.location.hostname}:8080/someMurghiPlease`)">
    Link to some other port on the same host
  </a>
a_rahmanshah
la source
1

Basé sur la réponse de Gary Hole , mais change les URL lors du chargement de la page au lieu d'un clic.

Je voulais afficher l'url en utilisant css:

a:after {
  content: attr(href);
}

J'avais donc besoin que le href de l'ancre soit converti pour contenir l'URL réelle qui serait visitée.

function fixPortUrls(){
  var nodeArray = document.querySelectorAll('a[href]');
  for (var i = 0; i < nodeArray.length; i++) {
    var a = nodeArray[i];
    // a -> e.g.: <a href=":8080/test">Test</a>
    var port = a.getAttribute('href').match(/^:(\d+)(.*)/);
    //port -> ['8080','/test/blah']
    if (port) {
      a.href = port[2]; //a -> <a href="https://stackoverflow.com/test">Test</a>
      a.port = port[1]; //a -> <a href="http://localhost:8080/test">Test</a>
    }
  }
}

Appelez la fonction ci-dessus lors du chargement de la page.

ou sur une seule ligne:

function fixPortUrls(){var na=document.querySelectorAll('a[href]');for(var i=0;i<na.length;i++){var a=na[i];var u=a.getAttribute('href').match(/^:(\d+)(.*)/);u&&a.href=u[2]&&a.port=u[1];}}

(J'utilise à la forplace de forEachcela fonctionne dans IE7.)

Sam Hasler
la source
0

Aucune des réponses que j'ai regardées (et je dirai que je ne les ai pas toutes lues) n'ajuste l'URL de telle sorte qu'un clic du milieu ou «ouvrir dans un nouvel onglet» fonctionne correctement - seulement un clic régulier pour suivre le lien. J'ai emprunté la réponse de Gary Greene, et au lieu d'ajuster l'URL à la volée, nous pouvons l'ajuster lors du chargement de la page:

...
<script>
function rewriteRelativePortUrls() {
    var links = document.getElementsByTagName("a");
    for (var i=0,max=links.length; i<max; i++)
    {
        var port = links[i].getAttribute("href").match(/^:(\d+)(.*)/);
        if (port)
        {
            newURL = window.location.origin + port[0]
            links[i].setAttribute("href",newURL)
        }    
    }
}

</script>
<body onload="rewriteRelativePortUrls()">
...
ddiepo
la source