【问题标题】:React-Router External linkReact-Router 外部链接
【发布时间】:2017-08-12 09:13:24
【问题描述】:

由于我在 react 应用程序中使用 react-router 来处理我的路由,我很好奇是否有办法重定向到外部资源。

说有人击中:

example.com/privacy-policy

我希望它重定向到:

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

我发现完全零帮助避免在我的 index.html 加载时用普通 JS 编写它,例如:

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

【问题讨论】:

  • 你使用的是哪个 React 路由器?
  • 我使用的是 3.x 版
  • 只需更改 window.location.href 即可进行正式重定向。
  • @AmirhosseinMehrvarzi 实际上没有任何意义。你能更具体一点或举个例子吗?另外我不确定你是否注意到,但是这个问题已经有一个处理 React 和 React Router 的公认答案,这就是问题所在。
  • @Relic 您需要在 if 条件中将其用作您的 url。几天前我遇到了类似的问题,发现这种方法简单有效。它立即重定向。 Accepted answer 是一个 Routing 解决方案(虽然它违反了 Route 原则,但考虑到 Route 架构是用于 App 内部导航 而不是外部),它不不适用于像我这样的任何环境

标签: javascript reactjs redirect react-router react-router-redux


【解决方案1】:

这是使用 React Router 重定向到外部链接的单行代码:

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

它使用 React 纯组件概念将组件的代码简化为单个函数,而不是渲染任何内容,而是将浏览器重定向到外部 URL。

适用于 React Router 3 和 4。

【讨论】:

  • 这可行,但我一直在寻找更优雅的可扩展解决方案。看看我想出了什么,因为它让我可以更进一步地重定向 MobileApps 等(不是 ReactNative,真正的原生应用程序)。现在我正在做的不是解决我的问题的正确方法,但为了解决这个问题,我建议你也调查一下我的解决方案,如果只是为了不同的观点。
  • 这在我看来并不是那么干净。我宁愿诚实地使用锚标签。其次,点击浏览器上的后退按钮会返回路由,然后重定向回example.zendesk.com/hc/en-us/articles/…
  • 要获得更好的后退按钮行为(验证您的应用程序),请使用 window.location.replace('example.com')
  • 没有答案,原始帖子仅询问客户端重定向,同时意识到没有 301 或 302 类型的真正重定向支持。
  • window.location.href 不是最优的。如果用户在被重定向后单击浏览器的“返回”按钮,她将到达将立即再次重定向她的路由。为避免这种情况,最好使用window.location.replace()。来源:stackoverflow.com/a/506004/163411
【解决方案2】:

使用 react-router 的 Link 组件,您可以做到这一点。在 "to" 属性中,您可以指定 3 种类型的数据:

  • 字符串:链接位置的字符串表示形式,通过连接位置的路径名、搜索和哈希属性创建。
  • 对象:可以具有以下任何属性的对象:
    • 路径名:表示要链接到的路径的字符串。
    • 搜索:查询参数的字符串表示形式。
    • hash:要放入 URL 的哈希,例如#a 哈希。
    • 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" />

您还可以传递您想要的道具,例如标题、id、className 等。

【讨论】:

  • 使用路径名将不起作用,至少在最新版本中是这样。无论如何它都会预先设置当前的基本路径
  • @Lorenzo 我已经使用它并且它正在工作!
  • 这对我不起作用。
  • 在 React-router 5 中对我不起作用
  • 为我工作,react-router 5.2.0
【解决方案3】:

不需要使用 react-router 中的&lt;Link /&gt; 组件。

如果您想转到外部链接,请使用锚标记。

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

【讨论】:

  • OP 询问如何以编程方式而不是声明方式进行操作
  • 不相关且具有误导性的答案。
  • 如果你使用这个,添加rel="noopener noreferrer"&lt;a&gt;
  • 很好的答案,不是每个人都会关心,只要他们能成功。
  • 好点! react-router 旨在处理应用程序内部导航,因此,尽管可以创建自定义元素,但应使用简单的锚标记创建外部链接。
【解决方案4】:

它不需要请求反应路由器。这个动作可以原生完成,由浏览器提供。

只需使用window.location

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

另外,如果你想在新标签页中打开它:

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

【讨论】:

  • 这个答案不完整,不允许抽象或者它与路由器有关
  • 这是目标。它不需要请求反应路由器。此操作可以在本机完成,由浏览器提供。
  • 如果我们想在重定向到外部站点的同时动态传递 URL 以及 HTTP 状态代码怎么办。我有一些例子,但我的要求并不清楚。 gist.github.com/arasmussen/f2c01dc858481590f6bffae6b540632c
  • 我认为这应该被接受。可能 url 可以作为道具公开。
【解决方案5】:

实际上我最终构建了自己的组件。 &lt;Redirect&gt; 它从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 是一个框架,一个框架有很多价值。这是如何在反应框架内做到这一点。然而,它没有考虑到可以在这里包装的浏览器历史模块,这使得它更加有用。另请注意,“window.location”是 1999 年的做法。这只是将其添加到您的路由表以进行客户端路由的一种方式。这不是一个“好的”解决方案。
  • 在 react-router v4 中你可以使用 render 代替组件
  • @Irrech "render instead component" 没有任何意义。如果您对该问题有答案,请添加并详细说明您将如何实施。
  • @MuhammadUmer 或者你只使用一个锚标签。 react-router 非常严格地用于在您的应用程序中进行路由。您可以不同意该设计决定(我知道 i 会),但这并不是“在 1999 年做得更好”,它只是做了同样的事情。
  • 如果我们想在重定向到外部站点的同时动态传递 URL 以及 HTTP 状态代码怎么办。我有一些例子,但我的要求并不清楚gist.github.com/arasmussen/f2c01dc858481590f6bffae6b540632c
【解决方案6】:

使用此处的一些信息,我想出了以下组件,您可以在路由声明中使用它。它与 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'}
/>

【讨论】:

    【解决方案7】:

    我遇到了同样的问题。我希望我的投资组合重定向到社交媒体句柄。之前我用{Link} from "react-router-dom". 就是重定向到这里的子目录,

    链接可用于在网站内路由网页。如果我们想重定向到外部链接,那么我们应该使用锚标记。像这样,

    【讨论】:

      【解决方案8】:

      我很幸运:

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

      【讨论】:

        【解决方案9】:

        最简单的解决方案是使用render function 并更改window.location

        <Route path="/goToGoogle"
               render={() => window.location = "https://www.google.com"} />
        

        如果你想要一个小的可重用组件,你可以像这样提取它:

        const ExternalRedirect = ({ to, ...routeProps }) => {
           return <Route {...routeProps} render={() => window.location = to} />;
        };
        

        然后像这样使用它(例如在您的路由器交换机中):

        <Switch>
            ...
            <ExternalRedirect exact path="/goToGoogle" to="https://www.google.com" />
        </Switch>
        

        【讨论】:

        • google.com" /> 会起作用吗?
        • 我不知道为什么这比使用外部目的地的后退按钮更好吗?
        • 写一个组件也许有一天会对你有所帮助。如果要更改重定向方式,则只需更改 ExternalRedirect 组件。例如。您想在重定向之前显示一个确认对话框:“您将被重定向到……继续?”
        【解决方案10】:

        您可以使用您的动态网址

        <Link to={{pathname:`${link}`}}>View</Link>
        
        

        【讨论】:

          【解决方案11】:

          我自己解决了这个问题(在我的网络应用程序中),方法是添加一个锚标记,而不使用 React 路由器中的任何东西,只是一个带有链接的普通锚标记,如图 screenshot of using anchor tag in a react.js app without using react router

          基本上,您不会将用户路由到应用内的另一个页面,因此您不能使用内部路由器,而是使用普通锚点。

          虽然这是针对非 react-native 解决方案,但您可以尝试。

          【讨论】:

            【解决方案12】:

            我认为 React-Router 不提供这种支持。 documentation 提到

            设置重定向到您的应用程序 中的另一个路由以维护旧 URL。

            您可以尝试改用 React-Redirect 之类的东西

            【讨论】:

            • React-Redirect 已弃用
            【解决方案13】:

            要扩展 Alan 的答案,您可以创建一个 &lt;Route/&gt;,将所有带有“to”属性的 &lt;Link/&gt; 重定向到正确的外部资源。

            下面是一个工作示例,可以直接放入您的&lt;Router&gt;

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

            【讨论】:

              【解决方案14】:

              我认为最好的解决方案是只使用一个普通的旧 &lt;a&gt; 标签。其他一切似乎都令人费解。 React 路由器是为单页应用程序中的导航而设计的,因此将它用于其他任何事情并没有多大意义。为已经内置在 &lt;a&gt; 标签中的东西制作一个完整的组件似乎......很傻?

              【讨论】:

              • React 让您提出诸如“如何将图像添加到网页”之类的问题
              【解决方案15】:

              适用于 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;
              

              【讨论】:

                【解决方案16】:

                我面临同样的问题。在 react js 中使用 http://https:// 解决了它。

                例如: &lt;a target="_blank" href="http://www.example.com/" title="example"&gt;See detail&lt;/a&gt;

                【讨论】:

                • 我猜我们正在 react-router 中寻找解决方案
                【解决方案17】:
                import React from "react";
                import { BrowserRouter as Router, Route } from "react-router-dom";
                
                function App() {
                  return (
                    <Router>
                      <Route path="/" exact>
                        {window.location.replace("http://agrosys.in")}
                      </Route>
                    </Router>
                  );
                }
                
                export default App;
                

                【讨论】:

                • 请添加一些 cmets,而不仅仅是代码,以便人们知道发生了什么
                【解决方案18】:
                // Create a custom redirect component
                
                function MyRedirect(props) {
                    window.location.replace(props.url);
                    return null
                }
                
                // Place the component inside the route with the destination url
                
                return (
                        <Router>
                            <Routes>
                                <Route path="/example" element={
                                    <MyRedirect url="https://example.com/"/>
                                } />
                            </Routes>
                        </Router>
                    );
                

                我正在使用react-router-dom v6

                代码创建了一个自定义重定向组件,当放置在您的渲染函数中时,它会重定向到指定的外部 url。

                【讨论】:

                  【解决方案19】:

                  将 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()

                  【讨论】:

                    【解决方案20】:

                    如果您使用服务器端渲染,您可以使用StaticRouter。将您的context 设置为props,然后在您的应用中添加&lt;Redirect path="/somewhere" /&gt; 组件。这个想法是每次 react-router 匹配一个重定向组件时,它都会在你传递给静态路由器的上下文中添加一些东西,让你知道你的路径匹配一个重定向组件。既然您知道您点击了重定向,您只需要检查这是否是您正在寻找的重定向。然后只需通过服务器重定向。 ctx.redirect('https://example/com')

                    【讨论】:

                    • 我正在寻求一种在客户端中执行此操作的方法。如果正确完成,它实际上应该在 DNS 级别完成。其次是在初始服务器请求中。由于我在 S3 上托管,因此没有服务器端。所以我现在被困住了,直到我们的开发运维人员可以在服务级别进行重定向。
                    • 你能做的是,&lt;Redirect push={ true } to="/pathtoredirect" /&gt;
                    【解决方案21】:

                    我能够使用以下方法在 react-router-dom 中实现重定向

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

                    就我而言,我一直在寻找一种方法,可以在用户访问根 URL http://myapp.com 时将其重定向到应用程序 http://myapp.com/newplace 中的其他位置。所以上面有帮助。

                    【讨论】:

                    • OP 明确指出他正在尝试重定向到外部资源,而不是同一应用程序内的路由。
                    • 很明显,我对我的用例很明确,如果他可以将它应用到他的上,我就放弃了。我的解决方案在我的应用程序中说,他可以以此为例。
                    • 如果你想向人们展示你的用例,请写一篇关于它的博客。 Stackoverflow 用于回答人们的查询,而不是您的用例。此外,实现用例的正确方法是 -
                    • 我发现这对于理解 react-routers &lt;Redirect 组件在重定向到外部 url 时可能无法正常工作非常有帮助。感谢您分享@walecloud - 如果它在博客文章中,我可能找不到。
                    【解决方案22】:

                    您现在可以通过使用 pathname 键向 to 提供对象来使用 React Link 链接到外部站点:

                    &lt;Link to={ { pathname: '//example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies' } } &gt;

                    如果在回调中发现需要使用JS生成链接,可以使用window.location.replace()window.location.assign()

                    过度使用window.location.replace(),正如其他好的答案所建议的那样,尝试使用window.location.assign()

                    window.location.replace() 将替换位置历史记录而不保留当前页面。

                    window.location.assign() 将转换到指定的 url,但会将上一页保存在浏览器历史记录中,从而允许正确的后退按钮功能。

                    https://developer.mozilla.org/en-US/docs/Web/API/Location/replace https://developer.mozilla.org/en-US/docs/Web/API/Location/assign

                    另外,如果您使用其他答案中提到的window.location = url 方法,我强烈建议您切换到window.location.href = url。 对此有一个激烈的争论,许多用户似乎坚决希望将较新的object 类型window.location 恢复为string 的原始实现,仅仅是因为他们可以(并且他们过分攻击任何说其他话的人),但是理论上,您可以中断访问 window.location 对象的其他库功能。

                    看看这个 convo。它是可怕的。 Javascript: Setting location.href versus location

                    【讨论】:

                      猜你喜欢
                      • 2017-06-11
                      • 2020-04-25
                      • 2022-08-24
                      • 2018-11-10
                      • 2015-07-16
                      • 2016-10-31
                      • 2021-01-09
                      • 1970-01-01
                      相关资源
                      最近更新 更多