प्रतिक्रिया-राउटर के साथ ब्राउज़र में / # / कैसे रोकें?


103

/#/प्रतिक्रिया-राउटर का उपयोग करते समय ब्राउज़र के एड्रेस बार में दिखाने से रोकने का कोई तरीका ? यही ReactJS के साथ है। यानी नए रूट शो localhost:3000/#/या जाने के लिए लिंक पर क्लिक करना localhost:3000/#/about। मार्ग पर निर्भर करता है।


1
यह HashHistoryआईएसओ का उपयोग करने के कारण है BrowserHistoryयह एसओ प्रश्न भी देखें जहां मैं इस विषय पर बहुत सारी पृष्ठभूमि जानकारी देता हूं।
Stijn de Witt

जवाबों:


78

प्रतिक्रिया-राउटर के संस्करणों 1, 2 और 3 के लिए, URL मैपिंग स्कीम के लिए मार्ग सेट करने का सही तरीका इतिहास कार्यान्वयन को historyपैरामीटर में शामिल करना है <Router>। से इतिहास प्रलेखन :

संक्षेप में, एक इतिहास जानता है कि परिवर्तनों के लिए ब्राउज़र के पता बार को कैसे सुनना है और URL को किसी स्थान ऑब्जेक्ट में पार्स करना है जो राउटर का उपयोग मार्गों से मिलान करने और घटकों के सही सेट को प्रस्तुत करने के लिए कर सकता है।

संस्करण 2 और 3

प्रतिक्रिया-राउटर 2 और 3 में, आपका मार्ग कॉन्फ़िगरेशन कोड कुछ इस तरह दिखाई देगा:

import { browserHistory } from 'react-router'
ReactDOM.render (( 
 <Router history={browserHistory} >
   ...
 </Router> 
), document.body);

संस्करण 1

संस्करण 1.x में, आप इसके बजाय निम्नलिखित का उपयोग करेंगे:

import createBrowserHistory from 'history/lib/createBrowserHistory'
ReactDOM.render (( 
  <Router history={createBrowserHistory()} >
   ...
  </Router> 
), document.body);

स्रोत: संस्करण 2.0 अपग्रेड गाइड

संस्करण 4

प्रतिक्रिया-राउटर के आगामी संस्करण 4 के लिए, सिंटैक्स ने एक महान सौदा बदल दिया है और यह आवश्यक है BrowserRouterकि राउटर रूट टैग के रूप में उपयोग किया जाए।

import BrowserRouter from 'react-router/BrowserRouter'
ReactDOM.render (( 
  <BrowserRouter>
   ...
 <BrowserRouter> 
), document.body);

स्रोत रिएक्ट राउटर संस्करण 4 डॉक्स


6
ध्यान दें कि historyएक स्टैंड-अलोन पैकेज है जिसे आपको इंस्टॉल करना होगा।
Jan Klimo

4
उन्होंने browserHistoryv2.x में परिवर्तन किया : प्रतिक्रिया-राउटर अपग्रेड गाइड कीimport { browserHistory } from 'react-router' <Router history={browserHistory} /> जाँच करें
pistou

धन्यवाद @pistou, मैंने संस्करण 2.0 के उत्तर को अपडेट किया!
एडम ब्राउन

1
क्या hashHistory, इस क्वेरी को समाप्त करने का कोई तरीका है? http://localhost:8080/#/dashboard?_k=yqwtyu
कोन एंटोनकोस

2
@ मैट यह काम करता है, लेकिन सर्वर पर समर्थन की आवश्यकता है। ऐसा इसलिए क्योंकि जब आप रिफ्रेश होते हैं, तो आप सर्वर को पथ वाले URL से मारते हैं।
1939 में स्टिजेन डे विट जू

40
Router.run(routes, Router.HistoryLocation, function (Handler) {
  React.render(<Handler/>, document.body);
});

वर्तमान संस्करण 0.11 और आगे के लिए, आपको जोड़ने की आवश्यकता Router.HistoryLocationहै Router.run()<Routes>अब पदावनत हो गए हैं। 0.12.x HistoryLocation कार्यान्वयन के लिए नवीनीकरण मार्गदर्शिका देखें


1
इसने मेरे ऐप को पूरी तरह बर्बाद कर दिया। ऐसा लगता है कि उनका वर्तमान कार्यान्वयन छोटी गाड़ी है?
निंजानेर

2
@ निंजा शायद प्रतिक्रिया और प्रतिक्रिया-राउटर के लिए सटीक संस्करण संख्याओं के साथ एक नया प्रश्न पोस्ट करते हैं, कोड और त्रुटियों को प्राप्त करने में विफल।
22 अक्टूबर को pxwise

@ चेट लगता है जैसे राउटर-राउटर डॉक्स ने फेरबदल किया है। अपग्रेड गाइड में पाए गए HistoryLocation के एकमात्र संदर्भ के लिए अद्यतन लिंक।
pxwise

21

यदि आपको IE8 का समर्थन करने की आवश्यकता नहीं है, तो आप ब्राउज़र इतिहास का उपयोग कर सकते हैं और प्रतिक्रिया-राउटर का उपयोग करेंगे window.pushState हैश सेट बजाय ।

यह करने के लिए वास्तव में क्या आप उपयोग कर रहे हैं कि प्रतिक्रिया रूटर के संस्करण पर निर्भर करता है:


धन्यवाद @ बेन-एपरट, मैं इसे अभी प्राप्त करता हूं।
विशालकाय एल्क

1
मैंने कहा <Routes location="history">कि यह सब ठीक काम करता है, जब तक कि जब आप मार्ग पर ब्राउज़र को ताज़ा नहीं करते हैं, localhost:3000/aboutतब मुझे 404 त्रुटि मिलती है। क्या यह अपेक्षित है, मैं उपयोग कर रहा हूँ python -m SimpleHTTPServer 3000?
विशालकाय एल्क

5
आपको यह सुनिश्चित करने की आवश्यकता है कि आपका सर्वरसाइड पुश स्थिति url को संभाल सकता है। इस उदाहरण में, इसका मतलब है कि आपको बस यह सुनिश्चित करने की ज़रूरत है कि जो भी आपका ऐप सर्व कर रहा है वह हमेशा हर url को उसी रूट पर भेजता है। ताकि /aboutवास्तव में आपका रूट पेज लोड हो जाए /। अन्यथा आपका सर्वर एक ऐसे मार्ग की तलाश करने की कोशिश कर रहा है जो मेल खाता है /aboutऔर कुछ नहीं (404) पाता है। मैं व्यक्तिगत रूप से अजगर का उपयोग नहीं करता हूं, लेकिन आप आमतौर पर /*या /.*-> /काम करता है के लिए एक मैनुअल मार्ग ढूंढते हैं - या यह html5Modeआपके सर्वर सेटिंग्स में यूआरएल नामक कुछ हो सकता है ।
माइक ड्राइवर

3
IE9 पुशस्टेट का समर्थन नहीं करता है - तो यह वास्तव में है "यदि आपको IE9 का समर्थन करने की आवश्यकता नहीं है"? काश मैं गलत होता।
कायमन

1
यह github लिंक एक पृष्ठ है जो अब नहीं मिला है।
k00k

9

इसे पूरा करने के लिए आप वास्तव में .htaccess का उपयोग कर सकते हैं। ब्राउज़र को आमतौर पर क्वेरी स्ट्रिंग सीमांकक की आवश्यकता होती है ?या #यह निर्धारित करने के लिए कि क्वेरी स्ट्रिंग कहां से शुरू होती है और निर्देशिका पथ समाप्त हो जाते हैं। अंतिम परिणाम जो हम चाहते हैं, www.mysite.com/dir इसलिए हमें उस मुद्दे को पकड़ने की जरूरत है जो वेब सर्वर उस निर्देशिका के लिए खोजता है, जो यह सोचता है कि हमने पूछा था /dir। इसलिए हम .htaccessपरियोजना की जड़ में एक फ़ाइल रखते हैं।

    # Setting up apache options
    AddDefaultCharset utf-8
    Options +FollowSymlinks -MultiViews -Indexes
    RewriteEngine on

    # Setting up apache options (Godaddy specific)
    #DirectoryIndex index.php
    #RewriteBase /


    # Defining the rewrite rules
    RewriteCond %{SCRIPT_FILENAME} !-d
    RewriteCond %{SCRIPT_FILENAME} !-f

    RewriteRule ^.*$ ./index.html

फिर आप window.location.pathname के साथ क्वेरी पैरामीटर प्राप्त करते हैं

यदि आप चाहें तो आप प्रतिक्रिया मार्गों का उपयोग करने से बच सकते हैं और यदि आप चाहें तो केवल यूआरएल और ब्राउज़र इतिहास में हेरफेर कर सकते हैं। उम्मीद है कि यह किसी की मदद करता है ...


Jboss के बराबर क्या है?
राघवन

5

इतिहास पैकेज स्थापित करें

npm install history --save

अगला आयात createHistory और इतिहास से उपयोग करें

import { createHistory, useBasename } from 'history';
...
const history = useBasename(createHistory)({
  basename: '/root' 
});

अगर आपका app url www.example.com/myApp है, तो / root / myApp होना चाहिए।

राउटर के लिए इतिहास चर पास करें

render((
  <Router history={history}>
    ...
  </Router>
), document.getElementById('example'));

अब आपके सभी लिंक टैग के लिए सभी रास्तों के सामने एक "/" जोड़ा गया है।

<Link to="/somewhere">somewhere</Link>

समाधान की प्रेरणा रिएक्ट-राउटर उदाहरण से आई है जो दुर्भाग्य से, उनके एपीआई में ठीक से प्रलेखित नहीं थी।


क्या इसके लिए नोड सर्वर की आवश्यकता है? मैं उसी URL शैली को प्राप्त करने की कोशिश कर रहा हूं, लेकिन केवल क्लाइंट पक्ष के माध्यम से। क्या यह संभव है?
सेबेस्टियलोनो

1
नहींं, आपको नोड सर्वर की आवश्यकता नहीं है। वास्तव में मैं django बैकएंड पर चल रहा हूं। लेकिन आपको शायद टूल के लिए नोड की आवश्यकता है।
मोक्स

1
ठीक है, मैंने इस दृष्टिकोण की कोशिश की। जब मैं F5 को हिट करता हूं, तो मुझे जो कुछ भी मिलता है वह "नहीं मिला" है। क्या इस इतिहास से निपटना संभव है?
सेबेस्टियलोनो

अगर यू नहीं मिल रहा है, तो वह सर्वर द्वारा लौटा दिया जाता है। इसका मतलब यह है कि यूआरएल पैटर्न प्रतिक्रिया राउटर का हिस्सा नहीं है।
मोक्स

1
हां, थोड़ा और पढ़ने के बाद, सब कुछ स्पष्ट हो गया। मैंने इसे बिना चाबी के हैशस्टोरॉन के साथ जाना समाप्त कर दिया।
सेबेस्टियलोनो

3

हैश के बाद क्या प्रदर्शित करना है, इसे संभालने का एक और तरीका है (इसलिए यदि आप पुशस्टेट का उपयोग नहीं करते हैं!) तो आपका कस्टमलायलेशन बनाना है और इसे ReactRouter निर्माण पर लोड करना है।

छूट के लिए, यदि आप क्रॉलिंग के लिए Google स्पेक्स का अनुपालन करने के लिए हैशबंग url (# के साथ!) चाहते हैं, तो आप एक HashbangLocation.js फ़ाइल बना सकते हैं जो मुख्य रूप से मूल HashLocation की प्रतिलिपि बनाती है जैसे:

'use strict';

var LocationActions = require('../../node_modules/react-router/lib/actions/LocationActions');
var History = require('../../node_modules/react-router/lib/History');

var _listeners = [];
var _isListening = false;
var _actionType;

function notifyChange(type) {
  if (type === LocationActions.PUSH) History.length += 1;

  var change = {
    path: HashbangLocation.getCurrentPath(),
    type: type
  };

  _listeners.forEach(function (listener) {
    listener.call(HashbangLocation, change);
  });
}

function slashToHashbang(path) {
  return "!" + path.replace(/^\//, '');
}

function ensureSlash() {

  var path = HashbangLocation.getCurrentPath();
  if (path.charAt(0) === '/') {
    return true;
  }HashbangLocation.replace('/' + path);

  return false;
}

function onHashChange() {
  if (ensureSlash()) {
    // If we don't have an _actionType then all we know is the hash
    // changed. It was probably caused by the user clicking the Back
    // button, but may have also been the Forward button or manual
    // manipulation. So just guess 'pop'.
    var curActionType = _actionType;
    _actionType = null;
    notifyChange(curActionType || LocationActions.POP);
  }
}

/**
 * A Location that uses `window.location.hash`.
 */
var HashbangLocation = {

  addChangeListener: function addChangeListener(listener) {
    _listeners.push(listener);

    // Do this BEFORE listening for hashchange.
    ensureSlash();

    if (!_isListening) {
      if (window.addEventListener) {
        window.addEventListener('hashchange', onHashChange, false);
      } else {
        window.attachEvent('onhashchange', onHashChange);
      }

      _isListening = true;
    }
  },

  removeChangeListener: function removeChangeListener(listener) {
    _listeners = _listeners.filter(function (l) {
      return l !== listener;
    });

    if (_listeners.length === 0) {
      if (window.removeEventListener) {
        window.removeEventListener('hashchange', onHashChange, false);
      } else {
        window.removeEvent('onhashchange', onHashChange);
      }

      _isListening = false;
    }
  },

  push: function push(path) {
    _actionType = LocationActions.PUSH;
    window.location.hash = slashToHashbang(path);
  },

  replace: function replace(path) {
    _actionType = LocationActions.REPLACE;
    window.location.replace(window.location.pathname + window.location.search + '#' + slashToHashbang(path));
  },

  pop: function pop() {
    _actionType = LocationActions.POP;
    History.back();
  },

  getCurrentPath: function getCurrentPath() {
    return decodeURI(
    // We can't use window.location.hash here because it's not
    // consistent across browsers - Firefox will pre-decode it!
    "/" + (window.location.href.split('#!')[1] || ''));
  },

  toString: function toString() {
    return '<HashbangLocation>';
  }

};

module.exports = HashbangLocation;

नोट SlashToHashbang फ़ंक्शन।

फिर आपको बस करना होगा

ReactRouter.create({location: HashbangLocation})

और बस :-)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.