¿URL relativa a un número de puerto diferente en un hipervínculo?

136

¿Hay alguna forma sin Javascript / scripting del lado del servidor para vincular a un número de puerto diferente en el mismo cuadro, si no sé el nombre de host?

p.ej:

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

(Este ejemplo no funciona ya que solo tratará: 8080 como una cadena a la que quiero navegar)

Ciaran McNulty
fuente
Debido a que muchas personas a continuación se apilaron con soluciones del lado del servidor, el NGINX $http_hostvar funciona, por ejemplo, return 200 '<html><body><iframe id="ic" src="http://$http_host:2812/"></iframe></body></html>es decir, en un /etc/nginx/conf.d/strange.confarchivo.
MarkHu

Respuestas:

52

Sería bueno si esto pudiera funcionar, y no veo por qué no porque :es un carácter reservado para la separación de puertos dentro del componente URI, por lo que el navegador podría interpretarlo de manera realista como un puerto relativo a esta URL, pero desafortunadamente no ty no hay forma de que lo haga.

Por lo tanto, necesitará Javascript para hacer esto;

// 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);

Probado en Firefox 4

Violín: http://jsfiddle.net/JtF39/79/


Actualización : Se corrigió un error para agregar el puerto al final de la URL y también se agregó soporte para las URL relativas y absolutas que se agregarán al final:

<a href=":8080/test/blah">Test absolute</a>
<a href=":7051./test/blah">Test relative</a>
Gary Green
fuente
1
así que sin JavaScript no hay una solución verdadera
Daniel Ruf
2
No hay forma de hacer esto sin Javascript.
Gary Green
66
Esto no funcionó en Safari 6. El problema es que no está eliminando el puerto de la URL relativa, por lo que termina con algo así como http://myhost:8080/:8080para href=":8080". Puede agregar esta línea en `target.port = port [1];` para arreglar esto. target.href = target.href.replace("/:"+target.port, "");(No es una solución perfecta, ya que es un hallazgo / reemplazar, pero es bueno para casos sencillos en los que no está preocupado por el puerto de cuerdas estar en la URL.)
zekel
1
Mi solución fue crear una clase ASP.NET que genere la URL. Es esencialmente la misma solución que la anterior, solo del lado del servidor.
rookie1024
77
Por favor no use esta solución . Se romperá por completo en clientes sin Javascript, probablemente incluyendo muchos dispositivos de accesibilidad como lectores de pantalla. En su lugar, genere las URL en el lado del servidor.
Sven Slootweg
88

Que tal esto:

Modifique el número de puerto al hacer clic:

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

Sin embargo, si pasa el mouse sobre el enlace, no muestra el enlace con el nuevo número de puerto incluido. No es hasta que hace clic en él que agrega el número de puerto. Además, si el usuario hace clic con el botón derecho en el enlace y hace "Copiar ubicación del enlace", obtiene la URL sin modificar sin el número de puerto. Entonces esto no es ideal.

Aquí hay un método para cambiar la URL justo después de que se cargue la página, por lo que al pasar el mouse sobre el enlace o al hacer "Copiar ubicación del enlace" obtendrá la URL actualizada con el número de puerto:

<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
fuente
Gracias por señalar las advertencias, de las que estaba al tanto. En mi situación, las advertencias no son muy importantes, y prefiero la simplicidad de su primera solución. Estaba casi seguro de que ya había votado por su respuesta, pero el software parece pensar que no, y probablemente la memoria del software es más confiable que la mía. Lo he votado (¿de nuevo?).
Kevin Walker
He resuelto el misterio: en su lugar, accidentalmente voté por una de las otras respuestas. Ups No tengo suficiente reputación para revertir mi voto accidental.
Kevin Walker
<a href="#" onclick="javascript:event.target.port=8888">port 8888</a>técnicamente no debería funcionar, de acuerdo con las especificaciones de w3 . event.targetse supone que es readonly. ¡Pero parece funcionar para mí en Chrome y Firefox!
JamesThomasMoon1979
¡Una solución de revestimiento es genial! +1
Piotr Kula
Gracias. Me gusta su segunda solución porque puedo configurar la href del elemento en el HTML como una alternativa al URI más probable.
Duncan X Simpson
56

Puedes hacerlo fácilmente usando document.write y la URL se mostrará correctamente cuando pases el mouse sobre ella. Tampoco necesita una identificación única con este método y funciona con Chrome, Firefox e IE. Dado que solo hacemos referencia a variables y no cargamos ningún script externo, el uso de document.write aquí no afectará el rendimiento de carga de la página.

<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
fuente
3
Simple y elegante! No sé por qué esto no tiene más votos positivos, tal vez solo sea un recién llegado.
Kevin H. Patterson
55
También tenga en cuenta que no necesita incluir window.location.protocolparte, solo comience con '//'.
kbrock
Parece legitimo. Elegante.
Jay
Muy práctico y elegante.
Robert Lucian Chiriac
Solo para decir que document.writehoy en día no se recomienda universalmente. Sería mejor hacer algo comomyElement.innerHTML = '...'
mwfearnley
13

Modifique el número de puerto al pasar el mouse:

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

Esta es una mejora de https://stackoverflow.com/a/13522508/1497139 que no tiene el inconveniente de no mostrar el enlace correctamente.

Wolfgang Fahl
fuente
5

Sin JavaScript, tendrá que confiar en algunos scripts del lado del servidor. Por ejemplo, si está utilizando ASP, algo así como ...

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

Deberia trabajar. Sin embargo, el formato exacto dependerá de la tecnología que esté utilizando.

gdt
fuente
4

Después de luchar con esto, descubrí que SERVER_NAME es una variable reservada. Entonces, si está en la página (www.example.com:8080), debería poder soltar el 8080 e invocar otro puerto. Por ejemplo, este código modificado me funcionó y me mueve de cualquier puerto base al puerto 8069 (reemplace su puerto según sea necesario)

<div>
    <a href="http://<?php print
    $_SERVER{'SERVER_NAME'}; ?>:8069"><img
    src="images/example.png"/>Example Base (http)</a>
</div>
Landis Arnold
fuente
1
Buena solución PHP! Puede omitir el protocolo para que se detecte automáticamente:<a href="https://<?php print $_SERVER{'SERVER_NAME'}; ?>:8069">
ADTC
3

Es mejor obtener la URL de las variables del servidor:

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

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

No necesita javascript complicado: simplemente inserte un nodo de script después de su ancla, luego obtenga el nodo en javascript y modifique su propiedad href con el método window.location.origin .

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

La propiedad id debe ser única en toda la página, por lo que es posible que desee utilizar otro método para recuperar objetos de nodo.

Probado con apache y Firefox en Linux.

MUY Bélgica
fuente
Por alguna razón, esto no funcionó del todo para mí: dirigió el navegador a http//localhost:8081, tenga en cuenta los dos puntos faltantes. Acabo de eliminar la parte del protocolo por completo ya que Chrome asumió http de todos modos.
joerick
¿Cómo lo probaste?
MUY Bélgica
1
Creo que esto debería ser window.location.hostnameen su lugar. Ver developer.mozilla.org/en-US/docs/Web/API/Location
mwfearnley
2

Esta solución me parece más limpia

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

Basado en la respuesta de Gary Hole , pero cambia las URL en la carga de la página en lugar de hacer clic.

Quería mostrar la url usando css:

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

Entonces necesitaba que la href del ancla se convirtiera para contener la url real que se visitaría.

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>
    }
  }
}

Llame a la función anterior al cargar la página.

o en una línea:

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];}}

(Estoy usando en forlugar de forEachpor lo que funciona en IE7).

Sam Hasler
fuente
0

Ninguna de las respuestas que vi (y diré, no las leí todas) ajusta la URL de manera que un clic central o "abrir en una pestaña nueva" funcione correctamente, solo un clic normal para seguir el enlace. Tomé prestado la respuesta de Gary Greene, y en lugar de ajustar la URL sobre la marcha, podemos ajustarla cuando se carga la página:

...
<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
fuente