Tautan Eksternal React-Router

113

Karena saya menggunakan react-router untuk menangani rute saya di aplikasi react, saya ingin tahu apakah ada cara untuk mengalihkan ke sumber daya eksternal.

Katakanlah seseorang memukul:

example.com/privacy-policy

Saya ingin ini dialihkan ke:

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

Saya menemukan tidak ada bantuan dalam menghindari menulisnya dalam JS biasa di index.html saya memuat dengan sesuatu seperti:

if ( window.location.path === "privacy-policy" ){
  window.location = "example.zendesk.com/hc/en-us/articles/123456789-Privacy-Policies"
}
Eric Hodonsky
sumber
Router React mana yang Anda gunakan?
Tyler McGinnis
Saya menggunakan versi 3.x
Eric Hodonsky
1
Cukup ubah window.location.hrefuntuk memiliki pengalihan formal.
Amirhossein Mehrvarzi
2
@Amirhosseininehrvarzi sebenarnya tidak berarti apa-apa. Bisakah Anda lebih spesifik atau memberi contoh? Juga saya tidak yakin apakah Anda telah memperhatikan tetapi pertanyaan ini sudah memiliki jawaban yang diterima berhubungan dengan React & React Router yang merupakan pertanyaannya.
Eric Hodonsky
1
@Relic Anda perlu menggunakannya sebagai url Anda dalam kondisi if Anda. Saya mengalami masalah serupa beberapa hari yang lalu dan menemukan cara ini sederhana dan efektif. Ini segera dialihkan. Jawaban yang diterima adalah solusi Perutean (Meskipun melanggar prinsip Rute, mengingat arsitektur Rute adalah untuk navigasi di dalam Aplikasi bukan untuk di luar) yang tidak berfungsi untuk lingkungan apa pun seperti milik saya
Amirhossein Mehrvarzi

Jawaban:

170

Berikut ini satu baris untuk menggunakan React Router untuk mengarahkan ke tautan eksternal:

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

Ia menggunakan konsep komponen murni React untuk mengurangi kode komponen menjadi satu fungsi yang, alih-alih merender apa pun, mengalihkan browser ke URL eksternal.

Bekerja baik pada React Router 3 dan 4.

Evgeny Lukianchikov
sumber
2
Ini berfungsi tetapi saya sedang mencari solusi skalabel yang lebih elegan. Lihat apa yang saya dapatkan karena memungkinkan saya melangkah lebih jauh dengan pengalihan untuk MobileApps dll (Bukan ReactNative, aplikasi yang benar-benar Asli). Sekarang apa yang saya lakukan bukanlah cara yang tepat untuk menyelesaikan masalah saya, tetapi untuk memecahkan masalah ini saya sarankan Anda menyelidiki solusi saya juga jika tidak ada yang lain selain dari perspektif yang berbeda.
Eric Hodonsky
1
Ini tidak sebersih itu dalam pikiranku. Saya lebih suka menggunakan tag anchor dengan jujur. Kedua, menekan tombol kembali di browser mengembalikan Anda rute yang kemudian dialihkan kembali ke example.zendesk.com/hc/en-us/articles/…
Jonathan Rys
11
Untuk perilaku tombol kembali yang lebih baik (verifikasi untuk aplikasi Anda), gunakan window.location.replace (' example.com' )
MattC
1
Tidak ada jawaban yang tepat, postingan asli hanya menanyakan tentang pengalihan klien, SAAT menyadari bahwa tidak ada dukungan pengalihan sejati tipe 301 atau 302.
Eric Hodonsky
50

Tidak perlu menggunakan <Link />komponen dari react-router.

Jika Anda ingin pergi ke tautan eksternal, gunakan tag jangkar.

<a target="_blank" href="https://meetflo.zendesk.com/hc/en-us/articles/230425728-Privacy-Policies">Policies</a>
Diego Laciar
sumber
20
OP bertanya bagaimana melakukannya secara terprogram, bukan secara deklaratif
Eric Hodonsky
13
Jawaban tidak terkait & menyesatkan.
Priya Ranjan Singh
1
Jika Anda menggunakan ini, tambahkan rel="noopener noreferrer"ke<a>
S ..
5
Jawaban yang bagus, tidak semua orang akan peduli selama mereka berhasil.
FrankByte.com
39

Saya akhirnya membangun Komponen saya sendiri. <Redirect> Dibutuhkan info dari react-routerelemen sehingga saya bisa menyimpannya di rute saya. Seperti:

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

Berikut adalah komponen saya, siapa pun yang penasaran:

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;

EDIT - CATATAN: Ini dengan react-router: 3.0.5, tidak sesederhana itu di 4.x.

Eric Hodonsky
sumber
Anda tidak HARUS melakukan apa pun, bereaksi adalah kerangka kerja, dan ada banyak nilai dalam kerangka kerja. INILAH cara melakukannya dalam kerangka react. Namun, ini TIDAK memperhitungkan modul riwayat browser yang dapat dibungkus di sini, menjadikannya lebih berguna. Juga Harap dicatat "window.location" adalah bagaimana hal itu dilakukan pada tahun 1999. Ini hanyalah cara untuk menambahkannya ke tabel rute Anda untuk perutean sisi klien. Ini bukan solusi yang "baik".
Eric Hodonsky
di react -router v4 Anda dapat menggunakan render sebagai gantinya komponen
Irrech
3
@Irech "render sebagai gantinya komponen" tidak ada artinya. Jika Anda memiliki jawaban atas pertanyaan tersebut, harap tambahkan dan berikan beberapa detail tentang bagaimana Anda akan menerapkannya.
Eric Hodonsky
3
@MuhammadUmer atau Anda cukup menggunakan tag anchor. react-router secara ketat dimaksudkan untuk merutekan hanya dalam aplikasi Anda. Anda dapat tidak setuju dengan keputusan desain itu (saya tahu saya setuju ), tetapi tidak "dilakukan lebih baik pada tahun 1999", itu hanya dilakukan dengan cara yang sama.
Worc
21

Itu tidak perlu meminta router react. Tindakan ini dapat dilakukan secara native dan disediakan oleh browser.

gunakan saja window.location

class RedirectPage extends React.Component {
  componentDidMount(){
    window.location.replace('http://www.google.com')
  }
}
Alan
sumber
1
Jawaban ini tidak lengkap, tidak memungkinkan abstraksi atau hubungannya dengan router
Eric Hodonsky
8
Inilah tujuannya. Itu tidak perlu meminta router react. Tindakan ini dapat dilakukan secara native dan disediakan oleh browser.
Alan
10

Dengan komponen Link dari react-router Anda dapat melakukan itu. Di prop " ke " Anda dapat menentukan 3 jenis data:

  • a string : Representasi string dari lokasi Tautan, dibuat dengan menggabungkan nama lokasi lokasi, pencarian, dan properti hash.
  • sebuah objek : Sebuah objek yang dapat memiliki salah satu dari properti berikut ini:
    • pathname : String yang merepresentasikan jalur yang akan ditautkan.
    • search : Representasi string dari parameter kueri.
    • hash : Sebuah hash untuk dimasukkan ke dalam URL, misalnya # a-hash.
    • state : Status untuk mempertahankan lokasi.
  • a function : Sebuah fungsi yang dilewatkan ke lokasi saat ini sebagai argumen dan yang harus mengembalikan representasi lokasi sebagai string atau sebagai objek

Untuk contoh Anda (tautan eksternal):

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

Anda dapat melakukan hal berikut:

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

Anda juga dapat mengirimkan props yang Anda inginkan seperti title, id, className, dll.

Víctor Daniel
sumber
1
Ini adalah solusi paling sederhana dan berfungsi dengan baik.
hPNJ7MHTyg
5

Menggunakan beberapa info di sini, saya datang dengan komponen berikut yang dapat Anda gunakan dalam deklarasi rute Anda. Ini kompatibel dengan React Router v4.

Ini menggunakan skrip jenis, tetapi harus cukup mudah untuk dikonversi ke javascript asli:

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;
      }}
    />
  );
};

Dan gunakan dengan:

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

Saya beruntung dengan ini:

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

Saya tidak berpikir React-Router menyediakan dukungan ini. The dokumentasi menyebutkan

<Redirect> menyiapkan pengalihan ke rute lain dalam aplikasi Anda untuk mempertahankan URL lama.

Anda dapat mencoba menggunakan sesuatu seperti React-Redirect sebagai gantinya

ytibrewala
sumber
1

Untuk memperluas jawaban Alan, Anda dapat membuat <Route/>yang mengalihkan semua <Link/>dengan atribut "ke" yang berisi 'http:' atau 'https:' ke sumber daya eksternal yang benar.

Di bawah ini adalah contoh kerja yang dapat ditempatkan langsung ke file <Router>.

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

UNTUK V3, meskipun mungkin bekerja untuk V4. Keluar dari jawaban Eric, saya perlu melakukan lebih banyak, seperti menangani pengembangan lokal di mana 'http' tidak ada di url. Saya juga mengalihkan ke aplikasi lain di server yang sama.

Ditambahkan ke file router:

import RedirectOnServer from './components/RedirectOnServer';

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

Dan Komponennya:

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
sumber
-1

Menggunakan React with Typescript Anda mendapatkan kesalahan karena fungsinya harus mengembalikan elemen react, bukan void. Jadi saya melakukannya dengan cara ini menggunakan metode render Route (dan menggunakan React router v4):

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

Di mana Anda juga bisa menggunakan window.location.assign(), window.location.replace()dll

chezwhite.dll
sumber
-2

Jika Anda menggunakan rending sisi server, Anda dapat menggunakan StaticRouter. Dengan contextsebagai Anda propsdan kemudian menambahkan <Redirect path="/somewhere" />komponen di aplikasi Anda. Idenya adalah setiap react-router cocok dengan komponen redirect, itu akan menambahkan sesuatu ke dalam konteks yang Anda berikan ke router statis untuk memberi tahu Anda bahwa jalur Anda cocok dengan komponen pengalihan. Sekarang setelah Anda tahu bahwa Anda menekan redirect, Anda hanya perlu memeriksa apakah itu pengalihan yang Anda cari. lalu alihkan melalui server. ctx.redirect('https://example/com').

Rei Dien
sumber
Saya meminta cara untuk melakukannya di klien. Ini sebenarnya harus dilakukan di tingkat DNS jika dilakukan dengan benar. Kedua akan menjadi permintaan server awal. Karena saya menghosting di S3, tidak ada sisi server. JADI, saya terhenti untuk saat ini hingga staf operasi pengembang kami dapat melakukan pengalihan di Tingkat Layanan.
Eric Hodonsky
apa yang dapat Anda lakukan adalah,<Redirect push={ true } to="/pathtoredirect" />
Rei Dien
-4

Saya dapat mencapai pengalihan di react-router-dom menggunakan yang berikut ini

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

Untuk kasus saya, saya sedang mencari cara untuk mengarahkan pengguna setiap kali mereka mengunjungi URL root http://myapp.comke tempat lain di dalam aplikasi http://myapp.com/newplace. jadi hal di atas membantu.

walecloud.dll
sumber
2
OP dengan jelas menyatakan bahwa dia mencoba mengalihkan ke sumber daya eksternal, bukan ke rute di dalam aplikasi yang sama.
Neets
Jelas, saya spesifik tentang kasus penggunaan saya dan membatalkannya jika dia bisa menerapkannya padanya. solusi saya mengatakan dalam aplikasi saya, dia dapat menggunakannya sebagai contoh.
walecloud
1
Jika Anda ingin menunjukkan kasus penggunaan Anda kepada orang-orang, silakan tulis blog tentang hal itu. Stackoverflow adalah untuk menjawab kueri yang dimiliki orang-orang, bukan kasus penggunaan Anda. Selain itu, cara yang benar untuk menerapkan kasus penggunaan Anda adalah - <Redirect from = "/" to = {{pathname: '/ YourRoute'}} />
Abhas