URL สัมพันธ์กับหมายเลขพอร์ตอื่นในไฮเปอร์ลิงก์หรือไม่


136

มีวิธีที่ไม่มี Javascript / สคริปต์ฝั่งเซิร์ฟเวอร์เพื่อเชื่อมโยงไปยังหมายเลขพอร์ตอื่นในช่องเดียวกันหรือไม่หากฉันไม่ทราบชื่อโฮสต์

เช่น:

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

(ตัวอย่างนี้ใช้ไม่ได้เพราะจะถือว่า 8080 เป็นสตริงที่ฉันต้องการนำทางไป)


stackoverflow.com/questions/8317059/relative-path-but-for-portลองดูสิ ... มันใช้ได้สำหรับฉัน

เนื่องจากผู้คนจำนวนมากด้านล่างใช้โซลูชันฝั่งเซิร์ฟเวอร์ 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

คำตอบ:


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 สัมพัทธ์และแบบสัมบูรณ์ที่จะต่อท้าย:

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

1
ดังนั้นหากไม่มีจาวาสคริปต์ก็ไม่มีทางออกที่แท้จริง
Daniel Ruf

2
ไม่มีวิธีใดที่จะทำได้หากไม่มี Javascript
Gary Green

6
นี้ไม่ได้ทำงานใน Safari 6. ปัญหาคือว่าคุณไม่ได้ลบพอร์ตจาก URL ที่เกี่ยวข้องเพื่อให้คุณจบลงด้วยสิ่งที่ต้องการสำหรับhttp://myhost:8080/:8080 href=":8080"คุณสามารถเพิ่มบรรทัดนี้ใต้ "target.port = port [1];` เพื่อแก้ไขปัญหานี้ target.href = target.href.replace("/:"+target.port, "");(ไม่ใช่โซลูชันที่สมบูรณ์แบบเนื่องจากเป็นการค้นหา / แทนที่ แต่เหมาะสำหรับกรณีง่ายๆที่คุณไม่กังวลว่าสตริงพอร์ตจะอยู่ใน URL)
zekel

1
วิธีแก้ปัญหาของฉันคือสร้างคลาส ASP.NET ที่สร้าง URL โดยพื้นฐานแล้วเป็นโซลูชันเดียวกับข้างต้นเพียงฝั่งเซิร์ฟเวอร์
rookie1024

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

ขอบคุณ ฉันชอบโซลูชันที่สองของคุณเพราะฉันสามารถตั้งค่า href ขององค์ประกอบใน HTML เป็นทางเลือกสำหรับ URI ที่เป็นไปได้มากที่สุด
Duncan X Simpson

56

คุณสามารถทำได้อย่างง่ายดายโดยใช้ document.write และ 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
เรียบง่ายและสง่างาม! ฉันไม่รู้ว่าเหตุใดจึงไม่มีคะแนนโหวตเพิ่มขึ้น - อาจเป็นเพียงผู้มาสาย
Kevin H. Patterson

5
นอกจากนี้ยังทราบว่าคุณไม่จำเป็นต้องรวมถึงการมีส่วนร่วมเพียงแค่เริ่มต้นด้วยwindow.location.protocol '//'
kbrock

ดูเหมือนว่าเชื่อถือได้. สง่า
Jay

สะดวกและสง่างาม
Robert Lucian Chiriac

แค่จะบอกว่าdocument.writeเป็นเรื่องที่ไม่เป็นที่นิยมอย่างแพร่หลายในปัจจุบัน มันจะดีกว่าถ้าทำสิ่งที่ชอบmyElement.innerHTML = '...'
mwfearnley

13

แก้ไขหมายเลขพอร์ตเมื่อวางเมาส์เหนือ:

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

นี่คือการปรับปรุงของhttps://stackoverflow.com/a/13522508/1497139ซึ่งไม่มีการดึงกลับไม่แสดงลิงค์อย่างถูกต้อง


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

3

การรับ url จากตัวแปรเซิร์ฟเวอร์จะดีกว่า:

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

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

2

ไม่จำเป็นต้องใช้จาวาสคริปต์ที่ซับซ้อนเพียงแค่ใส่โหนดสคริปต์หลังจุดยึดของคุณจากนั้นรับโหนดในจาวาสคริปต์และแก้ไขคุณสมบัติhrefด้วยเมธอดwindow.location.origin

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

คุณสมบัติ id ต้องไม่ซ้ำกันทั้งหน้าดังนั้นคุณอาจต้องการใช้วิธีอื่นเพื่อดึงอ็อบเจ็กต์โหนด

ทดสอบกับ apache และ Firefox บน Linux


ด้วยเหตุผลบางอย่างสิ่งนี้ไม่ได้ผลสำหรับฉัน - มันสั่งให้เบราว์เซอร์http//localhost:8081สังเกตเครื่องหมายจุดคู่ที่หายไป ฉันเพิ่งลบส่วนของโปรโตคอลออกไปทั้งหมดเนื่องจาก Chrome ถือว่า http อยู่แล้ว
joerick

คุณทดสอบมันอย่างไร?
MUY Belgium

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

จากคำตอบของ Gary Holeแต่เปลี่ยน URL ในการโหลดหน้าแทนที่จะคลิก

ฉันต้องการแสดง url โดยใช้ 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()">
...
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.