URL relativo a un numero di porta diverso in un collegamento ipertestuale?


136

Esiste un modo senza Javascript / scripting lato server per collegarsi a un numero di porta diverso nella stessa casella, se non conosco il nome host?

per esempio:

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

(Questo esempio non funziona poiché tratterà solo: 8080 come una stringa in cui voglio navigare)



Poiché molte persone sotto accatastate con soluzioni lato server, NGINX $http_hostvar funziona, ad es .: return 200 '<html><body><iframe id="ic" src="http://$http_host:2812/"></iframe></body></html>in un /etc/nginx/conf.d/strange.conffile.
MarkHu,

Risposte:


52

Sarebbe bello se questo potesse funzionare, e non vedo perché no perché :è un carattere riservato per la separazione delle porte all'interno del componente URI, quindi il browser potrebbe interpretarlo realisticamente come una porta relativa a questo URL, ma sfortunatamente non lo fa ' te non c'è modo per farlo.

Avrai quindi bisogno di Javascript per farlo;

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

Testato in Firefox 4

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


Aggiornamento : bug corretto per l'aggiunta della porta alla fine dell'url e aggiunta del supporto per gli URL relativi e assoluti da aggiungere alla fine:

<a href=":8080/test/blah">Test absolute</a>
<a href=":7051./test/blah">Test relative</a>

1
quindi senza javascript non esiste una vera soluzione
Daniel Ruf,

2
Non c'è modo di farlo senza Javascript.
Gary Green,

6
Questo non ha funzionato in Safari 6. Il problema è che non stai rimuovendo la porta dall'URL relativo, quindi finisci con qualcosa di simile http://myhost:8080/:8080a href=":8080". Puoi aggiungere questa riga in `target.port = port [1];` per risolvere questo problema. target.href = target.href.replace("/:"+target.port, "");(Non è una soluzione perfetta, dal momento che è un trova / sostituisci, ma è buono per i casi semplici in cui non sei preoccupato che la stringa di porta sia nell'URL.)
zekel

1
La mia soluzione era quella di creare una classe ASP.NET che generasse l'URL. È essenzialmente la stessa soluzione di cui sopra, solo lato server.
rookie1024,

7
Si prega di non utilizzare questa soluzione . Si romperà completamente sui client senza Javascript, probabilmente includendo molti dispositivi di accessibilità come gli screen reader. Generare invece gli URL sul lato server.
Sven Slootweg,

88

Cosa ne pensi di questi:

Modifica il numero di porta al clic:

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

Tuttavia, se si passa il mouse sopra il collegamento, questo non mostra il collegamento con il nuovo numero di porta incluso. Non è fino a quando non fai clic su di esso che aggiunge il numero di porta. Inoltre, se l'utente fa clic con il pulsante destro del mouse sul collegamento e fa "Copia posizione collegamento", ottiene l'URL non modificato senza il numero di porta. Quindi questo non è l'ideale.

Ecco un metodo per cambiare l'URL subito dopo il caricamento della pagina, quindi passando il mouse sul link o facendo "Copia posizione link" otterrai l'URL aggiornato con il numero di porta:

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

Grazie per aver sottolineato le avvertenze, di cui ero a conoscenza. Nella mia situazione le avvertenze non sono molto importanti e preferisco la semplicità della tua prima soluzione. Ero quasi certo di aver già votato a favore della tua risposta, ma il software sembra non pensare, e probabilmente la memoria del software è più affidabile della mia. L'ho votato (di nuovo ??).
Kevin Walker,

Ho risolto il mistero: ho invece votato accidentalmente una delle altre risposte. Ops. Non ho abbastanza reputazione per annullare il mio voto accidentale.
Kevin Walker,

<a href="#" onclick="javascript:event.target.port=8888">port 8888</a>tecnicamente non dovrebbe funzionare, secondo le specifiche w3 . event.targetdovrebbe essere readonly. Ma sembra funzionare per me su Chrome e Firefox!
JamesThomasMoon1979,

Una soluzione di rivestimento è fantastica! +1
Piotr Kula

Grazie. Mi piace la tua seconda soluzione perché posso impostare l'href dell'elemento nell'HTML come fallback all'URI più probabile.
Duncan X Simpson

56

Puoi farlo facilmente usando document.write e l'URL verrà visualizzato correttamente quando ci passi sopra. Inoltre, non è necessario un ID univoco con questo metodo e funziona con Chrome, FireFox e IE. Poiché stiamo solo facendo riferimento a variabili e non stiamo caricando alcun script esterno, l'utilizzo di document.write qui non influirà sulle prestazioni del caricamento della pagina.

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

3
Semplice ed elegante! Non so perché questo non abbia più voti positivi - forse è solo un ritardatario.
Kevin H. Patterson,

5
inoltre, non è necessario includere la window.location.protocolparte, solo a partire da '//'.
Kbrock,

Sembra giusto. Elegante.
Jay,

Molto pratico ed elegante.
Robert Lucian Chiriac,

Solo per dire che document.writeoggigiorno è praticamente universalmente sconsigliato. Sarebbe meglio fare qualcosa di similemyElement.innerHTML = '...'
mwfearnley


5

Senza JavaScript, dovrai fare affidamento su alcuni script lato server. Ad esempio, se stai usando ASP, qualcosa come ...

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

dovrebbe funzionare. Tuttavia, il formato esatto dipenderà dalla tecnologia che stai utilizzando.


4

Dopo aver lottato con questo ho scoperto che SERVER_NAME è una variabile riservata. Quindi, se sei sulla pagina (www.example.com:8080) dovresti essere in grado di rilasciare l'8080 e invocare un'altra porta. Ad esempio questo codice modificato ha funzionato per me e mi sposta da qualsiasi porta di base alla porta 8069 (sostituisci la tua porta come richiesto)

<div>
    <a href="http://<?php print
    $_SERVER{'SERVER_NAME'}; ?>:8069"><img
    src="images/example.png"/>Example Base (http)</a>
</div>

1
Bella soluzione PHP! Puoi tralasciare il protocollo in modo che venga rilevato automaticamente:<a href="https://stackoverflow.com//<?php print $_SERVER{'SERVER_NAME'}; ?>:8069">
ADTC

3

È meglio ottenere l'URL dalle variabili del server:

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

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

2

Non è necessario complicato javascript: basta inserire un nodo script dopo l'ancoraggio, quindi ottenere il nodo in javascript e modificare la sua proprietà href con il metodo window.location.origin .

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

La proprietà id deve essere univoca per tutta la pagina, pertanto è possibile utilizzare altri metodi per recuperare gli oggetti nodo.

Testato con apache e Firefox su Linux.


Per qualche motivo questo non ha funzionato del tutto per me - ha indirizzato il browser a http//localhost:8081, notare i due punti mancanti. Ho appena rimosso del tutto la parte del protocollo da quando Chrome ha assunto comunque http.
Joerick,

Come l'hai provato?
MUY Belgio,

1
Penso che dovrebbe essere window.location.hostnameinvece. Vedi developer.mozilla.org/en-US/docs/Web/API/Location
mwfearnley

2

Questa soluzione mi sembra più pulita

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

1

Basato sulla risposta di Gary Hole , ma modifica gli URL al caricamento della pagina anziché al clic.

Volevo mostrare l'URL usando CSS:

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

Quindi avevo bisogno che l'href dell'ancora fosse convertito per contenere l'URL effettivo che sarebbe stato visitato.

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

Chiamare la funzione sopra al caricamento della pagina.

o su una riga:

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

(Sto usando forinvece di forEachcosì funziona in IE7.)


0

Nessuna delle risposte che ho guardato (e dirò che non le ho tutte lette) regola l'URL in modo tale che un clic centrale o "apri in una nuova scheda" funzionino correttamente - solo un clic normale per seguire il collegamento. Ho preso in prestito la risposta di Gary Greene e invece di modificare l'URL al volo, possiamo aggiustarlo quando la pagina viene caricata:

...
<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()">
...
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.