Зовнішнє посилання React-Router


113

Оскільки я використовую react-router для обробки моїх маршрутів у реагуючому додатку, мені цікаво, чи є спосіб перенаправити на зовнішній ресурс.

Скажіть, хто потрапив:

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 ви використовуєте?
Тайлер МакГінніс

Я використовую версію 3.x
Ерік Ходонський

1
Просто змініть, window.location.hrefщоб мати офіційне перенаправлення.
Amirhossein Mehrvarzi

2
@AmirhosseinMehrvarzi це насправді нічого не означає. Чи можете ви бути більш конкретними чи навести приклад? Також я не впевнений, чи помітили ви, але на це питання вже є прийнята відповідь, що стосується маршрутизатора React & React, саме про це йшлося.
Ерік Ходонський

1
@ Relic Вам потрібно використовувати це як URL-адресу у своєму випадку. У мене були подібні проблеми кілька днів тому, і цей спосіб виявився простим і ефективним. Він переадресовує негайно. Прийнята відповідь - це рішення маршрутизації (хоча воно порушує принципи маршруту, враховуючи, що архітектура маршруту призначена для навігації в додатку, а не для зовнішнього середовища), яка не працює для будь-якого середовища, як у мене
Amirhossein Mehrvarzi

Відповіді:


170

Ось однолінійка для використання маршрутизатора React для переадресації на зовнішнє посилання:

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

Він використовує концепцію чистого компонента React, щоб звести код компонента до єдиної функції, яка замість того, щоб нічого передати, переспрямовує браузер на зовнішню URL-адресу.

Працює як на React Router 3, так і на 4.


2
Це працює, але я шукав більш елегантне масштабоване рішення. Подивіться, що я придумав, як це дозволило мені перейти ще далі з переадресаціями для MobileApps тощо (Not ReactNative, справді Native програми). Тепер те, що я роблю, - це не правильний спосіб вирішити свою проблему, але для вирішення цієї проблеми я пропоную вам дослідити і моє рішення, якщо не заради іншої точки зору.
Ерік Ходонський

1
Це не дуже добре в моїй свідомості. Я вважаю за краще чесно використовувати тег прив’язки. По-друге, натискання кнопки "назад" у браузері повертає вам маршрут, який потім перенаправляє назад до example.zendesk.com/hc/en-us/articles/…
Джонатан Ріс

11
Для кращої поведінки кнопки повернення (перевірте свою програму) скористайтеся window.location.replace (' example.com' )
MattC

1
Жодна з відповідей не робить, оригінальний пост запитував лише про клієнтські переадресації, хоч усвідомлюючи, що немає вірної підтримки переадресації типу 301 або 302.
Ерік Ходонський

50

Немає необхідності використовувати <Link />компонент від react-router.

Якщо ви хочете перейти до зовнішнього посилання, використовуйте тег прив’язки.

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

20
ОП запитували, як це зробити програмно, а не декларативно
Ерік Ходонський,

13
Непов’язана та оманлива відповідь.
Priya Ranjan Singh

1
Якщо ви користуєтесь цим, додайте rel="noopener noreferrer"до<a>
S ..

5
Хороша відповідь, не всі будуть піклуватися до тих пір, поки вони змусять його працювати.
FrankByte.com

39

Я фактично закінчив будувати свій власний компонент. <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" - це було зроблено в 1999 році. Це лише спосіб додати його до таблиці маршрутів для маршрутизації на стороні клієнта. Це не "хороше" рішення.
Ерік Ходонський


3
@Irrech "візуалізувати замість компонента" нічого не означає. Якщо у вас є відповідь на запитання, будь ласка, додайте її та дайте детальну інформацію про те, як ви реалізуєте.
Ерік Ходонський

3
@MuhammadUmer або ви просто використовуєте якірний тег. react-router досить строго призначений для маршрутизації саме у вашій програмі. Ви не можете погодитися з таким дизайнерським рішенням (я знаю, що я роблю), але це не "зроблено краще в 1999 році", це просто зроблено так само.
Worc

21

Не потрібно запитувати маршрутизатор реагування. Цю дію можна здійснити як вдома, так і надає браузер.

просто використовувати window.location

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

1
Ця відповідь неповна, не дозволяє абстрагуватись або стосується маршрутизатора
Ерік Ходонський

8
Це і є мета. Не потрібно запитувати маршрутизатор реагування. Цю дію можна здійснити як вдома, так і надається браузером.
Алан

10

З компонентом Link реактора-маршрутизатора ви можете це зробити. У програмі " до " ви можете вказати 3 типи даних:

  • рядок : рядкове представлення місця розташування посилання, створене об'єднанням властивостей імені шляху, пошуку та хешу.
  • об’єкт : Об'єкт, який може мати будь-яке з наступних властивостей:
    • ім'я шляху : рядок, що представляє шлях до посилання.
    • пошук : рядкове подання параметрів запиту.
    • хеш : хеш, який потрібно ввести в URL, наприклад, # а-хеш.
    • 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 тощо.


1
Це найпростіше рішення і працює добре.
hPNJ7MHTyg

5

Використовуючи деяку інформацію тут, я придумав наступний компонент, який ви можете використовувати у своїх деклараціях про маршрут. Він сумісний з React Router v4.

Він використовує машинопис, але повинен бути досить прямим для перетворення на рідний JavaScript:

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

2

Мені пощастило з цим:

  <Route
    path="/example"
    component={() => {
    global.window && (global.window.location.href = 'https://example.com');
    return null;
    }}
/>

1

Я не думаю, що React-Router надає цю підтримку. У документації згадується

<Перенаправлення> встановлює переспрямування на інший маршрут у вашій програмі для підтримки старих URL-адрес.

Ви можете спробувати використовувати що - щось на зразок React-Redirect замість


1

Щоб розширити відповідь Алана, ви можете створити атрибути, <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. Виходячи з відповіді Еріка, мені потрібно було зробити трохи більше, як обробити місцевий розвиток, де в URL-адресі немає http. Я також переспрямовую на іншу програму на тому ж сервері.

Додано до файлу маршрутизатора:

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

Використовуючи React with Typescript, ви отримуєте помилку, оскільки функція повинна повертати елемент реагування, а не void. Тому я зробив це таким чином, використовуючи метод візуалізації маршрутів (і використовуючи маршрутизатор React 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" />компонент в вашому додатку. Ідея полягає в тому, що щоразу, як маршрутизатор реакцій відповідає компоненту переадресації, він додасть щось у контекст, який ви перейшли у статичний маршрутизатор, щоб повідомити, що ваш шлях відповідає компоненту переадресації. тепер, коли ви знаєте, що ви потрапили на переспрямування, вам просто потрібно перевірити, чи це переспрямування, яке ви шукаєте. потім просто перенаправляти через сервер. ctx.redirect('https://example/com').


Я прошу способу зробити це у клієнта. Це насправді слід зробити на рівні DNS, якщо зробити це правильно. Другий - у початковому запиті сервера. Оскільки я розміщую хостинг на S3, на стороні сервера немає. Так що я поки що застряг, поки наш хлопець-розробник не зможе зробити переадресацію на рівні обслуговування.
Ерік Ходонський

що ви можете зробити, це<Redirect push={ true } to="/pathtoredirect" />
Rei Dien

-4

Мені вдалося досягти переадресації в реакторі-маршрутизаторі, використовуючи наступне

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

У моєму випадку я шукав спосіб перенаправити користувачів кожного разу, коли вони відвідують кореневу URL-адресу http://myapp.comкудись ще в додатку http://myapp.com/newplace. тому вищесказане допомогло.


2
ОП чітко заявляє, що він намагається перенаправити на зовнішній ресурс, а не на маршрут всередині однієї програми.
Неєць

Ясна річ, я був конкретний щодо мого випадку використання і відмовився, якщо він зможе застосувати його до свого. моє рішення говорить у моєму додатку, він може використовувати це як приклад.
walecloud

1
Якщо ви хочете продемонструвати людям свій випадок використання, напишіть про це блог. Stackoverflow призначений для відповіді на запит, який мають люди, а не ваші випадки використання. Також правильним способом реалізації вашого випадку використання є - <Перенаправити з = "/" на = {{pathname: '/ YourRoute'}} />
Абхас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.