React-Router Внешняя ссылка

118

Поскольку я использую response-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 Router вы используете?
Тайлер МакГиннис
Я использую версию 3.x
Эрик Годонски
1
Просто перейдите window.location.hrefна формальное перенаправление.
Amirhossein Mehrvarzi 02
2
@AmirhosseinMehrvarzi, на самом деле это ничего не значит. Не могли бы вы уточнить или привести пример? Также я не уверен, заметили ли вы, но на этот вопрос уже есть принятый ответ, касающийся React & React Router, о чем и был вопрос.
Эрик Годонски
1
@Relic Вам нужно использовать это как URL-адрес в условии if. У меня была аналогичная проблема несколько дней назад, и я нашел этот способ простым и эффективным. Он немедленно перенаправляет. Принятый ответ - это решение для маршрутизации (хотя оно нарушает принципы маршрутизации, учитывая, что архитектура маршрута предназначена для навигации внутри приложения, а не для внешнего использования), которое не работает ни в одной среде, подобной моей,
Амирхосейн Мехрварци

Ответы:

174

Вот однострочный пример использования React Router для перенаправления на внешнюю ссылку:

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

Он использует концепцию чистого компонента React, чтобы свести код компонента к одной функции, которая вместо того, чтобы отображать что-либо, перенаправляет браузер на внешний URL-адрес.

Работает как на React Router 3, так и на 4.

Евгений Лукьянчиков
источник
2
Это работает, но я искал более элегантное масштабируемое решение. Посмотрите, что я придумал, поскольку это позволило мне пойти еще дальше с переадресацией для мобильных приложений и т. Д. (Не ReactNative, действительно нативные приложения). То, что я делаю, не является правильным способом решения моей проблемы, но для решения этой проблемы я предлагаю вам изучить и мое решение, хотя бы ради чего-то другого.
Eric Hodonsky
1
На самом деле это не так чисто в моей голове. Я бы предпочел честно использовать тег привязки. Во-вторых, нажатие кнопки «Назад» в браузере возвращает маршрут, который затем перенаправляет обратно на example.zendesk.com/hc/en-us/articles/…
Джонатан Райс,
11
Для лучшего поведения кнопки возврата (проверьте для своего приложения) используйте window.location.replace (' example.com' )
MattC
1
Ни один из ответов не отвечает, в исходном сообщении спрашивалось только о перенаправлении клиентов, при этом было известно, что нет поддержки истинного перенаправления типа 301 или 302.
Эрик Годонски
51

Нет необходимости использовать <Link />компонент от response-router.

Если вы хотите перейти по внешней ссылке, используйте тег привязки.

<a target="_blank" href="https://meetflo.zendesk.com/hc/en-us/articles/230425728-Privacy-Policies">Policies</a>
Диего Лациар
источник
23
ОП спрашивал, как это сделать программно, а не декларативно
Эрик Годонски
14
Несвязанный и вводящий в заблуждение ответ.
Прия Ранджан Сингх
1
Если вы все же используете это, добавьте rel="noopener noreferrer"к<a>
S ..
6
Хороший ответ, не всем будет все равно, пока он работает.
FrankByte.com
40

Фактически я создал свой собственный компонент. <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

Эрик Годонски
источник
вам НЕ НУЖНО ничего делать, react - это фреймворк, и он имеет большую ценность. Вот как это сделать в рамках React. Однако он НЕ принимает во внимание модуль истории браузера, который можно обернуть здесь, что делает его еще более полезным. Также обратите внимание, что "window.location" - это то, как это было сделано в 1999 году. Это просто способ добавить его в вашу таблицу маршрутов для маршрутизации на стороне клиента. Это не «хорошее» решение.
Эрик Годонски
в
react -router
3
@Irrech "рендеринг вместо компонента" ничего не значит. Если у вас есть ответ на вопрос, добавьте его и подробно опишите, как вы его реализуете.
Эрик Годонски
3
@MuhammadUmer или вы просто используете тег привязки. response-router довольно строго предназначен для маршрутизации внутри вашего приложения. Вы можете не согласиться с этим дизайнерским решением (я знаю , я делаю), но это не «сделать лучше в 1999 году», это просто сделать то же самое.
worc 02
Что, если мы хотим передать URL-адрес также динамически вместе с кодом состояния HTTP при перенаправлении на внешний сайт. У меня есть пример, но его неясно с моим требованием gist.github.com/arasmussen/f2c01dc858481590f6bffae6b540632c
Кришна Мани
21

Не нужно запрашивать реагирующий маршрутизатор. Это действие может быть выполнено изначально и обеспечивается браузером.

просто используйте window.location

class RedirectPage extends React.Component {
  componentDidMount(){
    window.location.replace('http://www.google.com')
  }
}
Алан
источник
1
Это неполный ответ, не допускающий абстракции или его отношение к маршрутизатору
Эрик Годонски,
8
Это цель. Не нужно запрашивать реагирующий маршрутизатор. Это действие может быть выполнено изначально и обеспечивается браузером.
Алан
Что, если мы хотим передать URL-адрес также динамически вместе с кодом состояния HTTP при перенаправлении на внешний сайт. У меня есть пример, но это не совсем понятно с моим требованием. gist.github.com/arasmussen/f2c01dc858481590f6bffae6b540632c
Кришна Мани
15

Это можно сделать с помощью компонента Link реактивного маршрутизатора. В опоре " to " вы можете указать 3 типа данных:

  • строка : строковое представление местоположения ссылки, созданное путем объединения пути, поиска и хеш-свойств местоположения.
  • объект : объект, который может иметь любое из следующих свойств:
    • pathname : строка, представляющая путь для ссылки.
    • поиск : строковое представление параметров запроса.
    • hash : хеш для вставки в URL, например # a-hash.
    • состояние : состояние, которое будет сохраняться в этом месте.
  • функция : функция, которой текущее местоположение передается в качестве аргумента и которая должна возвращать представление местоположения в виде строки или объекта.

Для вашего примера (внешняя ссылка):

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 и т. Д.

Виктор Даниэль
источник
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'}
/>
Йенс Бодал
источник
3

Мне с этим повезло:

  <Route
    path="/example"
    component={() => {
    global.window && (global.window.location.href = 'https://example.com');
    return null;
    }}
/>
Алекс Биллсон
источник
1

Я не думаю, что React-Router предоставляет такую ​​поддержку. В документации упоминается

<Redirect> устанавливает перенаправление на другой маршрут в вашем приложении для поддержки старых URL-адресов.

Вместо этого вы можете попробовать использовать что-то вроде React-Redirect

Ytibrewala
источник
1

Чтобы расширить ответ Алана, вы можете создать, <Route/>который перенаправляет все <Link/>атрибуты «to», содержащие «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. Исходя из ответа Эрика, мне нужно было сделать немного больше, например, обработать локальную разработку, где 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;
MattC
источник
-1

Используя React с Typescript, вы получите сообщение об ошибке, поскольку функция должна возвращать элемент реакции, а не void . Я сделал это таким образом, используя метод рендеринга Route (и используя маршрутизатор React v4):

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

Где вы могли бы вместо этого также использовать window.location.assign()и window.location.replace()т. Д.

Chezwhite
источник
-2

Если вы используете рендеринг на стороне сервера, вы можете использовать StaticRouter. С вашим contextas, propsа затем добавлением <Redirect path="/somewhere" />компонента в ваше приложение. Идея состоит в том, что каждый раз, когда response-router соответствует компоненту перенаправления, он будет добавлять что-то в контекст, который вы передали в статический маршрутизатор, чтобы вы знали, что ваш путь соответствует компоненту перенаправления. теперь, когда вы знаете, что попали в перенаправление, вам просто нужно проверить, является ли это перенаправлением, которое вы ищете. тогда просто перенаправьте через сервер. ctx.redirect('https://example/com').

Рей Дин
источник
Я прошу способ сделать это в клиенте. На самом деле это должно быть сделано на уровне DNS, если все сделано правильно. Второй будет в первоначальном запросе сервера. Поскольку я размещаю на S3, серверной части нет. Итак, я застрял, пока наш разработчик не сможет выполнить перенаправление на уровне обслуживания.
Эрик Годонски
то, что вы можете сделать,<Redirect push={ true } to="/pathtoredirect" />
Рей
-4

Мне удалось добиться перенаправления в response-router-dom, используя следующие

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

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

Walecloud
источник
2
В OP четко указано, что он пытается перенаправить на внешний ресурс, а не на маршрут внутри того же приложения.
Neets
Ясно, что я конкретизировал свой вариант использования и отказался от него, если он может применить его к своему. мое решение говорит в моем приложении, он мог бы использовать это в качестве примера.
walecloud
1
Если вы хотите продемонстрировать людям свой вариант использования, напишите об этом в блоге. Stackoverflow предназначен для ответа на запросы людей, а не для вашего варианта использования. Кроме того, правильный способ реализации вашего варианта использования - <Redirect from = "/" to = {{pathname: '/ YourRoute'}} />
Abhas