ลิงค์ภายนอกของ React-Router


125

เนื่องจากฉันใช้ react-router เพื่อจัดการเส้นทางของฉันในแอป react ฉันจึงสงสัยว่ามีวิธีเปลี่ยนเส้นทางไปยังทรัพยากรภายนอกหรือไม่

พูดว่ามีคนฮิต:

example.com/privacy-policy

ฉันต้องการให้เปลี่ยนเส้นทางไปที่:

example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies

ฉันพบว่าไม่มีความช่วยเหลือในการหลีกเลี่ยงการเขียนเป็น JS ธรรมดาที่การโหลด index.html ของฉันด้วยสิ่งที่ต้องการ:

if ( window.location.path === "privacy-policy" ){
  window.location = "example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies"
}

คุณใช้ React Router ตัวไหน
Tyler McGinnis

ฉันใช้เวอร์ชัน 3.x
Eric Hodonsky

1
เพียงแค่เปลี่ยนwindow.location.hrefให้มีการเปลี่ยนเส้นทางอย่างเป็นทางการ
Amirhossein Mehrvarzi

2
ที่จริงไม่ได้มีความหมายอะไรเลย คุณสามารถเจาะจงมากขึ้นหรือยกตัวอย่างได้ไหม ฉันไม่แน่ใจว่าคุณสังเกตเห็นหรือไม่ แต่คำถามนี้มีคำตอบที่ยอมรับแล้วเกี่ยวกับ React & React Router ซึ่งเป็นคำถามเกี่ยวกับ
Eric Hodonsky

1
@ Relic คุณต้องใช้เป็น url ใน if condition ของคุณ ฉันมีปัญหาคล้ายกันเมื่อสองสามวันก่อนและพบว่าวิธีนี้ง่ายและมีประสิทธิภาพ มันเปลี่ยนเส้นทางทันที คำตอบที่ยอมรับคือโซลูชันการกำหนดเส้นทาง (แม้ว่าจะละเมิดหลักการของเส้นทาง แต่เนื่องจากสถาปัตยกรรมเส้นทางใช้สำหรับการนำทางภายในแอปไม่ใช่สำหรับภายนอก) ซึ่งใช้ไม่ได้กับสภาพแวดล้อมใด ๆ เช่นของฉัน
Amirhossein Mehrvarzi

คำตอบ:


181

นี่คือหนึ่งซับสำหรับการใช้ React Router เพื่อเปลี่ยนเส้นทางไปยังลิงก์ภายนอก:

<Route path='/privacy-policy' component={() => { 
     window.location.href = 'https://example.com/1234'; 
     return null;
}}/>

ใช้แนวคิด React pure component เพื่อลดโค้ดของคอมโพเนนต์ให้เป็นฟังก์ชันเดียวที่แทนที่จะแสดงผลอะไรเลยเปลี่ยนเส้นทางเบราว์เซอร์ไปยัง URL ภายนอก

ทำงานได้ทั้งบน React Router 3 และ 4


2
วิธีนี้ใช้ได้ผล แต่ฉันกำลังมองหาโซลูชันที่ปรับขนาดได้ที่หรูหรากว่านี้ ดูสิ่งที่ฉันคิดขึ้นมาเพราะมันทำให้ฉันสามารถไปได้ไกลกว่าเดิมด้วยการเปลี่ยนเส้นทางสำหรับ MobileApps และอื่น ๆ (ไม่ใช่ ReactNative แอปเนทีฟอย่างแท้จริง) ตอนนี้สิ่งที่ฉันทำไม่ใช่วิธีที่ถูกต้องในการแก้ปัญหาของฉัน แต่ในการแก้ปัญหานี้ฉันขอแนะนำให้คุณตรวจสอบวิธีแก้ปัญหาของฉันด้วยหากไม่มีอะไรอื่นนอกจากมุมมองที่แตกต่างออกไป
Eric Hodonsky

1
นี่ไม่ใช่ความคิดที่สะอาดจริงๆ ฉันอยากจะใช้แท็กจุดยึดอย่างตรงไปตรงมา ประการที่สองการกดปุ่มย้อนกลับบนเบราว์เซอร์จะส่งคืนเส้นทางที่เปลี่ยนเส้นทางกลับไปที่example.zendesk.com/hc/en-us/articles/…
Jonathan Rys

12
เพื่อให้การทำงานของปุ่มย้อนกลับดีขึ้น (ยืนยันสำหรับแอปพลิเคชันของคุณ) ให้ใช้ window.location.replace (' example.com' )
MattC

1
ไม่มีคำตอบใด ๆ โพสต์ต้นฉบับกำลังถามเกี่ยวกับการเปลี่ยนเส้นทางของไคลเอ็นต์เท่านั้นในขณะที่ทราบว่าไม่มีการสนับสนุนการเปลี่ยนเส้นทางจริงประเภท 301 หรือ 302
Eric Hodonsky

53

ไม่จำเป็นต้องใช้<Link />ส่วนประกอบจาก react-router

หากคุณต้องการไปที่ลิงก์ภายนอกให้ใช้แท็กจุดยึด

<a target="_blank" href="https://meetflo.zendesk.com/hc/en-us/articles/230425728-Privacy-Policies">Policies</a>

23
OP กำลังถามว่าจะทำอย่างไรโดยใช้โปรแกรมไม่ใช่อย่างเปิดเผย
Eric Hodonsky

15
คำตอบที่ไม่เกี่ยวข้องและทำให้เข้าใจผิด
Priya Ranjan Singh

1
หากคุณใช้สิ่งนี้ให้เพิ่มrel="noopener noreferrer"ไปที่<a>
..

7
คำตอบที่ดีไม่ใช่ทุกคนที่จะใส่ใจตราบเท่าที่พวกเขาได้ผล
FrankByte.com

42

ฉันลงเอยด้วยการสร้างส่วนประกอบของตัวเอง <Redirect> ใช้ข้อมูลจากreact-routerองค์ประกอบดังนั้นฉันจึงสามารถเก็บไว้ในเส้นทางของฉันได้ เช่น:

<Route
  path="/privacy-policy"
  component={ Redirect }
  loc="https://meetflo.zendesk.com/hc/en-us/articles/230425728-Privacy-Policies"
  />

นี่คือส่วนประกอบของฉันในกรณีที่ใคร ๆ ก็สงสัย:

import React, { Component } from "react";

export class Redirect extends Component {
  constructor( props ){
    super();
    this.state = { ...props };
  }
  componentWillMount(){
    window.location = this.state.route.loc;
  }
  render(){
    return (<section>Redirecting...</section>);
  }
}

export default Redirect;

แก้ไข - หมายเหตุ: นี่คือด้วยreact-router: 3.0.5มันไม่ง่ายนักใน 4.x


คุณไม่ต้องทำอะไรเลยการตอบสนองเป็นกรอบและมีคุณค่ามากมายในกรอบ นี่คือวิธีการทำภายในกรอบปฏิกิริยา อย่างไรก็ตามไม่คำนึงถึงโมดูลประวัติเบราว์เซอร์ที่อาจรวมอยู่ในที่นี่ทำให้สิ่งนี้มีประโยชน์มากยิ่งขึ้น นอกจากนี้โปรดทราบว่า "window.location" เป็นวิธีการดำเนินการในปี 2542 นี่เป็นเพียงวิธีการเพิ่มลงในตารางเส้นทางของคุณสำหรับการกำหนดเส้นทางฝั่งไคลเอ็นต์ ไม่ใช่ทางออกที่ "ดี"
Eric Hodonsky

ใน react -router v4 คุณสามารถใช้ render แทน component
Irrech

3
@Irrech "render แทน component" ไม่มีความหมายอะไร หากคุณมีคำตอบสำหรับคำถามโปรดเพิ่มและให้รายละเอียดเกี่ยวกับวิธีการนำไปใช้
Eric Hodonsky

4
@MuhammadUmer หรือคุณเพียงแค่ใช้แท็กจุดยึด react-router ค่อนข้างมีไว้สำหรับการกำหนดเส้นทางภายในแอปพลิเคชันของคุณ คุณอาจไม่เห็นด้วยกับการตัดสินใจออกแบบนั้น (ฉันรู้ว่าฉันทำ) แต่มันไม่ได้ "ทำได้ดีกว่าในปี 1999" แต่ก็ทำแบบเดียวกัน
worc

จะเกิดอะไรขึ้นหากเราต้องการส่ง URL แบบไดนามิกพร้อมกับรหัสสถานะ HTTP ในขณะที่เปลี่ยนเส้นทางไปยังไซต์ภายนอก ฉันมีตัวอย่าง แต่มันไม่ชัดเจนกับข้อกำหนดของฉัน gist.github.com/arasmussen/f2c01dc858481590f6bffae6b540632c
กฤษณะมณี

26

ไม่จำเป็นต้องขอตอบสนองเราเตอร์ การดำเนินการนี้สามารถทำได้โดยกำเนิดและให้บริการโดยเบราว์เซอร์

เพียงแค่ใช้ window.location

class RedirectPage extends React.Component {
  componentDidMount(){
    window.location.replace('https://www.google.com')
  }
}

นอกจากนี้หากคุณต้องการเปิดในแท็บใหม่:

window.open('https://www.google.com', '_blank');

1
คำตอบนี้ไม่สมบูรณ์ไม่อนุญาตให้มีการเป็นนามธรรมหรือเกี่ยวข้องกับเราเตอร์
Eric Hodonsky

9
นี่คือเป้าหมาย ไม่จำเป็นต้องขอตอบสนองเราเตอร์ การดำเนินการนี้สามารถทำได้โดยกำเนิดและให้บริการโดยเบราว์เซอร์
Alan

จะเกิดอะไรขึ้นหากเราต้องการส่ง URL แบบไดนามิกพร้อมกับรหัสสถานะ HTTP ในขณะที่เปลี่ยนเส้นทางไปยังไซต์ภายนอก ฉันมีตัวอย่าง แต่ไม่ชัดเจนกับความต้องการของฉัน gist.github.com/arasmussen/f2c01dc858481590f6bffae6b540632c
กฤษณะมณี

24

ด้วยส่วนประกอบ Link ของ react-router คุณสามารถทำได้ ในส่วน " ถึง " คุณสามารถระบุข้อมูลได้ 3 ประเภท:

  • สตริง : การแสดงสตริงของตำแหน่งลิงก์ที่สร้างขึ้นโดยการเชื่อมต่อคุณสมบัติชื่อพา ธ การค้นหาและแฮชของตำแหน่ง
  • วัตถุ : วัตถุที่สามารถมีคุณสมบัติดังต่อไปนี้:
    • ชื่อพา ธ : สตริงที่แสดงเส้นทางที่จะเชื่อมโยง
    • ค้นหา : การแสดงสตริงของพารามิเตอร์การค้นหา
    • แฮช : แฮชสำหรับใส่ URL เช่น # a-hash
    • state : สถานะที่จะคงอยู่ไปยังตำแหน่งที่ตั้ง
  • ฟังก์ชัน : ฟังก์ชันที่ส่งผ่านตำแหน่งปัจจุบันเป็นอาร์กิวเมนต์และควรส่งคืนการแสดงตำแหน่งเป็นสตริงหรือเป็นวัตถุ

สำหรับตัวอย่างของคุณ (ลิงก์ภายนอก):

https://example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies

คุณสามารถทำสิ่งต่อไปนี้:

<Link to={{ pathname: "https://example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies" }} target="_blank" />

คุณยังสามารถส่งผ่านอุปกรณ์ประกอบฉากที่คุณต้องการให้เป็นเช่น title, id, className เป็นต้น


6

จากข้อมูลบางส่วนที่นี่ฉันได้สร้างองค์ประกอบต่อไปนี้ซึ่งคุณสามารถใช้ในการประกาศเส้นทางของคุณ เข้ากันได้กับ React Router v4

มันใช้ typescript แต่ควรค่อนข้างตรงไปตรงมาเพื่อแปลงเป็นจาวาสคริปต์ดั้งเดิม:

interface Props {
  exact?: boolean;
  link: string;
  path: string;
  sensitive?: boolean;
  strict?: boolean;
}

const ExternalRedirect: React.FC<Props> = (props: Props) => {
  const { link, ...routeProps } = props;

  return (
    <Route
      {...routeProps}
      render={() => {
        window.location.replace(props.link);
        return null;
      }}
    />
  );
};

และใช้กับ:

<ExternalRedirect
  exact={true}
  path={'/privacy-policy'}
  link={'https://example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies'}
/>


1

ฉันไม่คิดว่า React-Router ให้การสนับสนุนนี้ เอกสารระบุว่า

A <Redirect> ตั้งค่าการเปลี่ยนเส้นทางไปยังเส้นทางอื่นในแอปพลิเคชันของคุณเพื่อรักษา URL เก่า

คุณสามารถลองใช้บางอย่างเช่นReact-Redirectแทน


React-Redirect เลิกใช้งานแล้ว
Ajifos

1

หากต้องการขยายคำตอบของ Alan คุณสามารถสร้าง<Route/>ที่เปลี่ยนเส้นทางทั้งหมด<Link/>ที่มีแอตทริบิวต์ "ถึง" ที่มี "http:" หรือ "https:" ไปยังทรัพยากรภายนอกที่ถูกต้อง

ด้านล่างนี้เป็นตัวอย่างการทำงานซึ่งสามารถวางไว้ใน<Router>ไฟล์.

<Route path={['/http:', '/https:']} component={props => {
  window.location.replace(props.location.pathname.substr(1)) // substr(1) removes the preceding '/'
  return null
}}/>

0

สำหรับ V3 แม้ว่าอาจใช้งานได้กับ V4 หากไม่ได้รับคำตอบของ Eric ฉันต้องทำอีกเล็กน้อยเช่นจัดการกับการพัฒนาท้องถิ่นที่ไม่มี "http" อยู่ใน url ฉันกำลังเปลี่ยนเส้นทางไปยังแอปพลิเคชันอื่นบนเซิร์ฟเวอร์เดียวกัน

เพิ่มไปยังไฟล์เราเตอร์:

import RedirectOnServer from './components/RedirectOnServer';

       <Route path="/somelocalpath"
          component={RedirectOnServer}
          target="/someexternaltargetstring like cnn.com"
        />

และส่วนประกอบ:

import React, { Component } from "react";

export class RedirectOnServer extends Component {

  constructor(props) {
    super();
    //if the prefix is http or https, we add nothing
    let prefix = window.location.host.startsWith("http") ? "" : "http://";
    //using host here, as I'm redirecting to another location on the same host
    this.target = prefix + window.location.host + props.route.target;
  }
  componentDidMount() {
    window.location.replace(this.target);
  }
  render(){
    return (
      <div>
        <br />
        <span>Redirecting to {this.target}</span>
      </div>
    );
  }
}

export default RedirectOnServer;

-1

โดยใช้ปฏิกิริยากับ typescript voidคุณได้รับข้อผิดพลาดเป็นฟังก์ชั่นจะต้องกลับตอบสนององค์ประกอบไม่ ดังนั้นฉันจึงทำวิธีนี้โดยใช้วิธีการเรนเดอร์เส้นทาง (และใช้ React router v4):

redirectToHomePage = (): null => {
    window.location.reload();
    return null;
  };    
<Route exact path={'/'} render={this.redirectToHomePage} />

ที่คุณสามารถใช้แทนwindow.location.assign(), window.location.replace()ฯลฯ


-2

หากคุณใช้การเรนเดอร์ฝั่งเซิร์ฟเวอร์คุณสามารถใช้StaticRouterไฟล์. ด้วยคุณcontextเป็นpropsแล้วเพิ่ม<Redirect path="/somewhere" />องค์ประกอบใน app ของคุณ แนวคิดคือทุกครั้งที่ react-router จะจับคู่องค์ประกอบการเปลี่ยนเส้นทางซึ่งจะเพิ่มบางอย่างลงในบริบทที่คุณส่งผ่านไปยังเราเตอร์แบบคงที่เพื่อแจ้งให้คุณทราบว่าเส้นทางของคุณตรงกับองค์ประกอบการเปลี่ยนเส้นทาง ตอนนี้คุณรู้แล้วว่าคุณโดนเปลี่ยนเส้นทางคุณเพียงแค่ต้องตรวจสอบว่านั่นคือการเปลี่ยนเส้นทางที่คุณกำลังมองหาหรือไม่ จากนั้นก็เปลี่ยนเส้นทางผ่านเซิร์ฟเวอร์ ctx.redirect('https://example/com').


ฉันกำลังขอวิธีทำในไคลเอนต์ ที่จริงควรทำที่ระดับ DNS หากทำอย่างถูกต้อง ประการที่สองจะอยู่ในการร้องขอเซิร์ฟเวอร์เริ่มต้น เนื่องจากฉันโฮสต์บน S3 จึงไม่มีฝั่งเซิร์ฟเวอร์ ดังนั้นตอนนี้ฉันติดอยู่จนกว่านักพัฒนาซอฟต์แวร์ของเราจะสามารถเปลี่ยนเส้นทางที่ระดับบริการได้
Eric Hodonsky

สิ่งที่คุณทำได้คือ<Redirect push={ true } to="/pathtoredirect" />
Rei Dien

-4

ฉันสามารถเปลี่ยนเส้นทางใน react-router-dom ได้โดยใช้สิ่งต่อไปนี้

<Route exact path="/" component={() => <Redirect to={{ pathname: '/YourRoute' }} />} />

สำหรับกรณีของฉันฉันกำลังมองหาวิธีที่จะเปลี่ยนเส้นทางผู้ใช้เมื่อใดก็ตามที่พวกเขาไปที่ URL รากhttp://myapp.comไปที่อื่นภายใน http://myapp.com/newplaceapp ดังนั้นข้างต้นจึงช่วยได้


2
OP ระบุชัดเจนว่าเขาพยายามเปลี่ยนเส้นทางไปยังทรัพยากรภายนอกไม่ใช่เส้นทางภายในแอปเดียวกัน
Neets

เห็นได้ชัดว่าฉันเจาะจงเกี่ยวกับกรณีการใช้งานของฉันและทิ้งมันไปถ้าเขาสามารถนำไปใช้กับเขาได้ วิธีแก้ปัญหาของฉันบอกว่าภายในแอปของฉันเขาสามารถใช้เป็นตัวอย่างได้
walecloud

1
หากคุณต้องการแสดงกรณีการใช้งานของคุณให้กับผู้อื่นโปรดเขียนบล็อกเกี่ยวกับเรื่องนี้ Stackoverflow ใช้สำหรับตอบคำถามที่บุคคลอื่นมีไม่ใช่กรณีการใช้งานของคุณ นอกจากนี้วิธีที่ถูกต้องในการใช้กรณีการใช้งานของคุณคือ - <Redirect from = "/" to = {{pathname: '/ YourRoute'}} />
Abhas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.