Względny adres URL do innego numeru portu w hiperłączu?


138

Czy istnieje sposób bez JavaScript / skryptów po stronie serwera, aby połączyć się z innym numerem portu w tym samym polu, jeśli nie znam nazwy hosta?

na przykład:

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

(Ten przykład nie działa, ponieważ po prostu potraktuje: 8080 jako ciąg, do którego chcę przejść)



Ponieważ wiele osób poniżej stosowało rozwiązania po stronie serwera, NGINX $http_hostvar działa, np. return 200 '<html><body><iframe id="ic" src="http://$http_host:2812/"></iframe></body></html>W /etc/nginx/conf.d/strange.confpliku.
MarkHu

Odpowiedzi:


54

Byłoby miło, gdyby to zadziałało, a nie rozumiem, dlaczego nie, ponieważ :jest to zastrzeżony znak do separacji portów w składniku URI, więc przeglądarka mogłaby realistycznie zinterpretować to jako port w odniesieniu do tego adresu URL, ale niestety tak nie jest. t i nie da się tego zrobić.

Dlatego będziesz potrzebować do tego Javascript;

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

Przetestowano w przeglądarce Firefox 4

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


Aktualizacja : Naprawiono błąd związany z dołączaniem portu do końca adresu URL, a także dodano obsługę względnych i bezwzględnych adresów URL, które mają być dołączane na końcu:

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

1
więc bez javascript nie ma prawdziwego rozwiązania
Daniel Ruf

2
Nie da się tego zrobić bez Javascript.
Gary Green

6
To nie zadziałało w Safari 6. Problem polega na tym, że nie usuwasz portu z relatywnego adresu URL, więc otrzymujesz coś takiego jak http://myhost:8080/:8080for href=":8080". Możesz dodać tę linię w `target.port = port [1];`, aby to naprawić. target.href = target.href.replace("/:"+target.port, "");(Nie jest to idealne rozwiązanie, ponieważ jest to znajdź / zamień, ale jest dobre w prostych przypadkach, w których nie martwisz się, że ciąg portu znajduje się w adresie URL.)
zekel

1
Moim rozwiązaniem było utworzenie klasy ASP.NET, która generuje adres URL. Jest to zasadniczo to samo rozwiązanie, co powyżej, tylko po stronie serwera.
rookie1024

7
Proszę nie używać tego rozwiązania . Będzie to całkowicie rozbić na klientach bez Javascript, prawdopodobnie w tym dostępności wielu urządzeń takich jak czytniki ekranu. Zamiast tego wygeneruj adresy URL po stronie serwera.
Sven Slootweg

90

Co powiesz na te:

Zmień numer portu po kliknięciu:

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

Jeśli jednak najedziesz kursorem myszy na łącze, nie wyświetli się łącza z dołączonym nowym numerem portu. Dopiero gdy go klikniesz, doda numer portu. Ponadto, jeśli użytkownik kliknie łącze prawym przyciskiem myszy i wykona polecenie „Kopiuj adres łącza”, otrzyma niezmodyfikowany adres URL bez numeru portu. Więc to nie jest idealne.

Oto metoda zmiany adresu URL zaraz po załadowaniu strony, więc umieszczenie kursora myszy nad linkiem lub wykonanie polecenia „Kopiuj adres odnośnika” spowoduje wyświetlenie zaktualizowanego adresu URL z numerem portu:

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

Dziękuję za wskazanie zastrzeżeń, o których wiedziałem. W mojej sytuacji zastrzeżenia nie są zbyt ważne i wolę prostotę pierwszego rozwiązania. Byłem prawie pewien, że już zagłosowałem za twoją odpowiedzią, ale oprogramowanie wydaje się nie myśleć i prawdopodobnie pamięć oprogramowania jest bardziej niezawodna niż moja. Głosowałem za tym (znowu ??).
Kevin Walker

Rozwiązałem zagadkę: zamiast tego przypadkowo zagłosowałem za jedną z pozostałych odpowiedzi. Ups. Nie mam wystarczającej reputacji, aby cofnąć przypadkowe głosy za.
Kevin Walker

<a href="#" onclick="javascript:event.target.port=8888">port 8888</a>powinien technicznie nie działać, zgodnie ze specyfikacjami w3 . event.targetma być readonly. Ale wydaje mi się, że działa na mnie w Chrome i Firefox!
JamesThomasMoon1979

Jedno rozwiązanie liniowe jest świetne! +1
Piotr Kula

Dzięki. Podoba mi się twoje drugie rozwiązanie, ponieważ mogę ustawić href elementu w HTML jako rezerwę dla najbardziej prawdopodobnego URI.
Duncan X Simpson,

57

Możesz to łatwo zrobić za pomocą document.write, a adres URL będzie wyświetlany poprawnie po najechaniu na niego kursorem. Nie potrzebujesz również unikalnego identyfikatora przy użyciu tej metody i działa ona z przeglądarkami Chrome, FireFox i IE. Ponieważ odwołujemy się tylko do zmiennych i nie ładujemy żadnych zewnętrznych skryptów, użycie document.write w tym miejscu nie wpłynie na wydajność ładowania strony.

<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
Prosty i elegancki! Nie wiem, dlaczego nie ma więcej głosów pozytywnych - może to po prostu spóźnialski.
Kevin H. Patterson

5
Pamiętaj również, że nie musisz uwzględniać window.location.protocolczęści, wystarczy zacząć od '//'.
kbrock

Wydaje się legalne. Elegancki.
Jay

Naprawdę poręczny i elegancki.
Robert Lucian Chiriac

Wystarczy powiedzieć, że w document.writedzisiejszych czasach jest to mało zalecane. Lepiej byłoby zrobić coś takiegomyElement.innerHTML = '...'
mwfearnley


5

Bez JavaScript będziesz musiał polegać na skryptach po stronie serwera. Na przykład, jeśli używasz ASP, coś takiego ...

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

powinno działać. Jednak dokładny format będzie zależał od używanej technologii.


5

Po zmaganiach z tym stwierdziłem, że SERVER_NAME jest zarezerwowaną zmienną. Więc jeśli jesteś na stronie (www.example.com:8080), powinieneś być w stanie porzucić 8080 i wywołać inny port. Na przykład ten zmodyfikowany kod po prostu działał dla mnie i przenosi mnie z dowolnego portu podstawowego do portu 8069 (w razie potrzeby wymień port)

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

1
Niezłe rozwiązanie PHP! Możesz pominąć protokół, aby został wykryty automatycznie:<a href="https://<?php print $_SERVER{'SERVER_NAME'}; ?>:8069">
ADTC

3

Lepiej jest pobrać adres URL ze zmiennych serwera:

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

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

2

Nie ma potrzeby stosowania skomplikowanego javascript: po prostu wstaw węzeł skryptu po zakotwiczeniu, następnie pobierz węzeł w javascript i zmodyfikuj jego właściwość href za pomocą metody window.location.origin .

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

Właściwość id musi być unikalna na całej stronie, więc możesz chcieć użyć innej metody do pobierania obiektów węzłów.

Testowane z Apache i Firefox w systemie Linux.


Z jakiegoś powodu to nie zadziałało w moim przypadku - skierowało przeglądarkę do http//localhost:8081, zwróć uwagę na brakujący dwukropek. Właśnie całkowicie usunąłem część protokołu, ponieważ Chrome i tak założył http.
joerick,

Jak to przetestowałeś?
MUY Belgium

1
Myślę, że to powinno być window.location.hostnamezamiast tego. Zobacz developer.mozilla.org/en-US/docs/Web/API/Location
mwfearnley

2

To rozwiązanie wydaje mi się czystsze

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

1

Na podstawie odpowiedzi Gary'ego Hole'a , ale zmienia adresy URL po załadowaniu strony zamiast po kliknięciu.

Chciałem pokazać URL za pomocą css:

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

Potrzebowałem więc przekonwertować href kotwicy, aby zawierał rzeczywisty adres URL, który miał być odwiedzany.

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

Wywołaj powyższą funkcję podczas ładowania strony.

lub w jednej linii:

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

(Używam forzamiast, forEachwięc działa w IE7.)


0

Żadna z odpowiedzi, na które patrzyłem (i powiem, że nie przeczytałem ich wszystkich) nie dostosowuje adresu URL tak, aby środkowe kliknięcie lub „otwórz w nowej karcie” działało poprawnie - wystarczy zwykłe kliknięcie, aby przejść do linku. Zapożyczyłem z odpowiedzi Gary'ego Greene'a i zamiast dostosowywać adres URL w locie, możemy go dostosować podczas ładowania strony:

...
<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()">
...
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.