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.