到超链接中不同端口号的相对URL?


136

如果我不知道主机名,是否可以使用没有Javascript /服务器端脚本的方法链接到同一框中的其他端口号?

例如:

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

(此示例不起作用,因为它将:8080视为我想导航到的字符串)



由于下面有很多人都在使用服务器端解决方案,因此NGINX $http_hostvar可以工作,例如:return 200 '<html><body><iframe id="ic" src="http://$http_host:2812/"></iframe></body></html>即在/etc/nginx/conf.d/strange.conf文件中。
MarkHu '17

Answers:


52

如果这行得通,那就太好了,我不明白为什么不这样做,因为这:是URI组件内部用于端口分隔的保留字符,因此浏览器可以现实地将其解释为相对于该URL的端口,但不幸的是,它不会t,它无法做到这一点。

因此,您将需要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);

在Firefox 4中测试

小提琴: http : //jsfiddle.net/JtF39/79/


更新:修复了将端口附加到URL末尾的错误,并且还增加了对相对URL和绝对URL附加到末尾的支持:

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

1
因此,如果没有JavaScript,就没有真正的解决方案
Daniel Ruf,

2
没有Java语言就无法做到这一点。
加里·格林

6
这在Safari 6中不起作用。问题是您没有从相对URL中删除端口,因此最终得到了类似http://myhost:8080/:8080for的信息href=":8080"。您可以在“ target.port = port [1];”下添加此行以解决此问题。target.href = target.href.replace("/:"+target.port, "");(这不是一个完美的解决方案,因为它是查找/替换,但是它对于不担心URL中包含端口字符串的简单情况很有用。)
zekel 2012年

1
我的解决方案是制作一个生成URL的ASP.NET类。它基本上是与上述相同的解决方案,只是服务器端。
rookie1024 2014年

7
不要使用此解决方案。在没有Javascript的客户端上,它将完全中断,可能包括许多可访问性设备,例如屏幕阅读器。而是在服务器端生成URL。
Sven Slootweg

88

这些怎么样:

在单击时修改端口号:

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

但是,如果将鼠标悬停在链接上,则不会显示包含新端口号的链接。直到您单击它,它才会添加端口号。另外,如果用户右键单击链接并执行“复制链接位置”,则他们将获得未修改的URL,但不包含端口号。所以这不是理想的。

这是一种在页面加载后立即更改URL的方法,因此将鼠标悬停在链接上或执行“复制链接位置”将获得带有端口号的更新URL:

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

感谢您指出我所知道的警告。在我的情况下,警告并不是很重要,我更喜欢第一个解决方案的简单性。我几乎可以肯定的是,我已经对您的回答表示支持,但是该软件似乎认为没有,并且软件的内存可能比我的要可靠。我赞成(再次??)。
Kevin Walker

我解决了这个谜团:我不小心更改了其他答案之一。哎呀。我没有足够的声誉来扭转我的意外投票。
Kevin Walker

<a href="#" onclick="javascript:event.target.port=8888">port 8888</a>根据w3规范,从技术上讲应该不起作用。 event.target应该是readonly。但这似乎在Chrome和Firefox中对我有用!
JamesThomasMoon1979

一个内衬解决方案很棒!+1
Piotr Kula 2015年

谢谢。我喜欢您的第二个解决方案,因为我可以将HTML中的元素的href设置为最可能的URI的备用。
Duncan X Simpson

55

您可以使用document.write轻松完成此操作,将鼠标悬停在URL上即可正确显示该URL。您也不需要使用此方法的唯一ID,它可以与Chrome,FireFox和IE一起使用。由于我们仅引用变量而不加载任何外部脚本,因此在此处使用document.write不会影响页面加载性能。

<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
简洁大方!我不知道为什么这没有更多的赞成票-也许只是后来者。
凯文·H·帕特森

5
另请注意,您无需包含window.location.protocol部分,只需从开始即可'//'
kbrock 2015年

似乎是合法的。优雅。
周杰伦

真正方便和优雅。
罗伯特·卢西安·基里亚克

只是说,document.write在当今世界上普遍不建议这样做。最好做些这样的事情myElement.innerHTML = '...'
mwfearnley


5

没有JavaScript,您将不得不依靠某些服务器端脚本。例如,如果您使用的是ASP,则类似...

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

应该管用。但是,确切的格式将取决于您使用的技术。


4

经过努力,我发现SERVER_NAME实际上是一个保留变量。因此,如果您位于页面(www.example.com:8080)上,则应该可以删除8080并调用另一个端口。例如,此修改后的代码仅对我有用,并将我从任何基本端口移至端口8069(根据需要替换端口)

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

1
不错的PHP解决方案!您可以省略该协议,以便对其进行自动检测:<a href="https://stackoverflow.com//<?php print $_SERVER{'SERVER_NAME'}; ?>:8069">
ADTC '16

3

最好从服务器变量获取url:

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

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

2

无需复杂的javascript:只需在锚点后插入一个脚本节点,然后在javascript中获取该节点,然后使用window.location.origin方法修改其href属性。

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

id属性必须在整个页面范围内是唯一的,因此您可能要使用其他方法来检索节点对象。

在Linux上使用apache和Firefox进行了测试。


出于某种原因,这对我来说并不太有效-它将浏览器定向到http//localhost:8081,请注意缺少的冒号。由于Chrome仍假定使用http,因此我完全删除了协议部分。
joerick 2014年

您是如何测试的?
MUY比利时2014年

1
我认为应该window.location.hostname改为。请参阅developer.mozilla.org/en-US/docs/Web/API/Location
mwfearnley

2

这个解决方案对我来说看起来更干净

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

1

根据加里·霍尔的回答,但更改页面加载时的网址,而不是单击时更改。

我想使用CSS显示网址:

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

因此,我需要转换锚的href,以包含将要访问的实际URL。

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

在页面加载时调用上述函数。

或一行:

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

(我使用for而不是forEach在IE7中使用。)


0

我看过的所有答案(我都会说,我没有全部读完)都不会调整URL,以使单击中键或“在新标签页中打开”将正常运行-只有常规单击才能跟随链接。我借用了Gary Greene的答案,而不是即时调整URL,我们可以在页面加载时进行调整:

...
<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()">
...
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.