प्रतिक्रिया-राउटर यूआरएल काम नहीं करते हैं जब ताज़ा या मैन्युअल रूप से लिखते हैं


653

मैं रिएक्ट-राउटर का उपयोग कर रहा हूं और लिंक बटन पर क्लिक करने के दौरान यह ठीक काम करता है, लेकिन जब मैं अपने वेबपेज को रिफ्रेश करता हूं तो यह लोड नहीं होता है जो मुझे चाहिए।

उदाहरण के लिए, मैं अंदर हूं localhost/joblistऔर सब कुछ ठीक है क्योंकि मैं एक लिंक दबाने यहां पहुंचा था। लेकिन अगर मुझे मिले वेबपेज को रीफ्रेश किया जाए:

Cannot GET /joblist

डिफ़ॉल्ट रूप से, यह इस तरह काम नहीं करता था। शुरू में मैं के रूप में मेरे यूआरएल था localhost/#/और localhost/#/joblistऔर वे बिल्कुल ठीक काम किया। लेकिन मुझे इस तरह का URL पसंद नहीं है, इसलिए #मैंने इसे मिटाने की कोशिश की , मैंने लिखा:

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

इस समस्या के साथ ऐसा नहीं होता है localhost/, यह हमेशा वही लौटता है जो मैं चाहता हूं।

EDIT: यह ऐप सिंगल-पेज है, इसलिए /joblistकिसी भी सर्वर से कुछ भी पूछने की जरूरत नहीं है।

EDIT2: मेरा पूरा राउटर।

var routes = (
    <Route name="app" path="/" handler={App}>
        <Route name="joblist" path="/joblist" handler={JobList}/>
        <DefaultRoute handler={Dashboard}/>
        <NotFoundRoute handler={NotFound}/>
    </Route>
);

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

जब तक आप अपने मुख्य भ्रमण पृष्ठ को लोड करने के लिए htaccess का उपयोग नहीं करते हैं और अपने राउटर को लोकेशन का उपयोग करने के लिए कहते हैं। तब तक यह काम नहीं करेगा ..
चार्ल्स जॉन थॉम्पसन III

आपने उस #प्रतीक को कैसे मिटा दिया ? धन्यवाद!
सूडोप्लज

4
यदि आप S3 बाल्टी में अपनी प्रतिक्रिया ऐप की मेजबानी कर रहे हैं, तो आप बस त्रुटि दस्तावेज़ सेट कर सकते हैं index.html। यह सुनिश्चित करेगा कि index.htmlकोई बात नहीं क्या हिट है।
ट्रेवर हट्टो

मेरे मामले में, यह विंडोज़ में ठीक काम करता है लेकिन लिनक्स में नहीं
एजाज़ करीम

यह वह संदर्भ है जिसने मेरी समस्या को हल करने में मदद की: github.com/facebook/create-react-app/blob/master/packages/…
jimbotron

जवाबों:


1093

स्वीकृत उत्तर और इस प्रश्न की सामान्य प्रकृति ('काम नहीं करते') पर टिप्पणियों को देखते हुए, मैंने सोचा कि यह यहां शामिल मुद्दों के बारे में कुछ सामान्य स्पष्टीकरण के लिए एक अच्छी जगह हो सकती है। तो यह जवाब ओपी के विशिष्ट उपयोग के मामले में पृष्ठभूमि की जानकारी / विस्तार के रूप में है। कृपया मेरा साथ दें।

सर्वर-साइड बनाम क्लाइंट-साइड

इसके बारे में समझने वाली पहली बड़ी बात यह है कि अब ऐसे 2 स्थान हैं जहाँ URL की व्याख्या की जाती है, जबकि 'पुराने दिनों' में केवल 1 ही हुआ करता था। अतीत में, जब जीवन सरल था, तो कुछ उपयोगकर्ता http://example.com/aboutसर्वर के लिए एक अनुरोध भेजते थे , जो URL के पथ भाग का निरीक्षण करता था, निर्धारित करता था कि उपयोगकर्ता उस पृष्ठ के बारे में अनुरोध कर रहा था और फिर उस पृष्ठ को वापस भेज दिया।

क्लाइंट-साइड रूटिंग के साथ, जो कि रिएक्ट-राउटर प्रदान करता है, चीजें कम सरल हैं। सबसे पहले, ग्राहक के पास कोई जेएस कोड अभी तक लोड नहीं है। इसलिए पहले अनुरोध हमेशा सर्वर पर रहेगा। इसके बाद एक पेज वापस आएगा जिसमें रिएक्ट और रिएक्ट राउटर आदि लोड करने के लिए आवश्यक स्क्रिप्ट टैग शामिल हैं, केवल जब उन लिपियों को लोड किया जाता है तो चरण 2 शुरू होता है। चरण 2, जब 'हमारे बारे में' उदाहरण के लिए नेविगेशन लिंक पर क्लिक करता है, URL परिवर्तित किया जाता है केवल स्थानीय रूप से करने के लिए http://example.com/about(द्वारा ही संभव बनाया इतिहास एपीआई ), लेकिन सर्वर से कोई अनुरोध किया जाता है। इसके बजाय, रिएक्ट राउटर क्लाइंट पक्ष पर अपनी बात करता है, यह निर्धारित करता है कि कौन सा रिएक्ट इसे रेंडर और रेंडर करता है। अपने पृष्ठ के बारे में मानकर किसी भी REST कॉल करने की आवश्यकता नहीं है, यह पहले से ही किया गया है। आपने किसी भी सर्वर अनुरोध के बिना घर से हमारे बारे में संक्रमण किया है।

इसलिए मूल रूप से जब आप एक लिंक पर क्लिक करते हैं, तो कुछ जावास्क्रिप्ट रन करता है जो एड्रेस बार में URL को हेरफेर करता है, बिना पेज रिफ्रेश किए , जिसके कारण क्लाइंट पक्ष पर पेज ट्रांजिशन करने के लिए रिएक्ट राउटर होता है ।

लेकिन अब विचार करें कि क्या होगा यदि आप एड्रेस बार में URL को कॉपी-पेस्ट करते हैं और इसे किसी मित्र को ई-मेल करते हैं। आपके मित्र ने अभी तक आपकी वेबसाइट लोड नहीं की है। दूसरे शब्दों में, वह अभी भी चरण 1 में है । अभी तक उसकी मशीन पर कोई रिएक्ट राउटर नहीं चल रहा है। तो उसका ब्राउज़र एक सर्वर अनुरोध करेगा http://example.com/about

और यहीं से आपकी परेशानी शुरू होती है। अब तक, आप अपने सर्वर के वेबरोट पर केवल एक स्थिर HTML रखने के साथ दूर हो सकते हैं। लेकिन वह सर्वर से अनुरोध404 करने पर अन्य सभी URL के लिए त्रुटियां देगा । वही URL क्लाइंट साइड पर ठीक काम करते हैं , क्योंकि वहां रिएक्ट राउटर आपके लिए राउटिंग कर रहा होता है, लेकिन वे सर्वर साइड में फेल हो जाते हैं, जब तक कि आप अपना सर्वर उन्हें समझ नहीं लेते।

सर्वर- और क्लाइंट-साइड रूटिंग का मेल

यदि आप चाहते हैं कि http://example.com/aboutURL सर्वर और क्लाइंट-साइड दोनों पर काम करे, तो आपको सर्वर और क्लाइंट साइड दोनों पर इसके लिए रूट सेट करना होगा। सही समझ में आता है?

और यहीं से आपकी पसंद शुरू होती है। समाधान समस्या को पूरी तरह से दरकिनार करने से होता है, एक कैच-ऑल मार्ग के माध्यम से जो बूटस्ट्रैप एचटीएमएल को लौटाता है, फुल-ऑन आइसोमॉर्फिक दृष्टिकोण पर जहां सर्वर और क्लाइंट दोनों एक ही जेएस कोड चलाते हैं।

समस्या को पूरी तरह से दरकिनार करते हुए: हैश हिस्ट्री

ब्राउज़र इतिहास के बजाय हैश इतिहास के साथ , पृष्ठ के बारे में आपका URL कुछ इस तरह दिखाई देगा: हैश ( ) प्रतीक के बाद का हिस्सा सर्वर को नहीं भेजा जाता है। इसलिए सर्वर केवल उम्मीद के अनुसार इंडेक्स पेज देखता है और भेजता है। रिएक्ट-राउटर भाग को उठाएगा और सही पृष्ठ दिखाएगा।http://example.com/#/about#http://example.com/#/about

डाउनसाइड्स :

  • 'बदसूरत' यूआरएल
  • इस दृष्टिकोण के साथ सर्वर-साइड प्रतिपादन संभव नहीं है। जहाँ तक Search Engine Optimization (SEO) का सवाल है, आपकी वेबसाइट में एक पेज होता है जिस पर शायद ही कोई कंटेंट हो।

सबको पकड़ो

इस दृष्टिकोण के साथ, आप ब्राउज़र इतिहास का उपयोग करते हैं, लेकिन बस सर्वर पर एक कैच-ऑल सेट करें, जो आपको भेजता /*है index.html, प्रभावी रूप से आपको हैश इतिहास के साथ समान स्थिति देता है। हालांकि आपके पास स्वच्छ URL हैं और आप अपने सभी उपयोगकर्ता के पसंदीदा को अमान्य किए बिना बाद में इस योजना में सुधार कर सकते हैं।

डाउनसाइड्स :

  • और अधिक जटिल स्थापित करने के लिए
  • फिर भी कोई अच्छा एसईओ नहीं

संकर

हाइब्रिड दृष्टिकोण में आप विशिष्ट मार्गों के लिए विशिष्ट स्क्रिप्ट जोड़कर कैच-ऑल परिदृश्य पर विस्तार करते हैं। आप अपनी साइट के सबसे महत्वपूर्ण पृष्ठों को शामिल सामग्री के साथ वापस करने के लिए कुछ सरल PHP स्क्रिप्ट बना सकते हैं, इसलिए Googlebot कम से कम यह देख सकता है कि आपके पृष्ठ पर क्या है।

डाउनसाइड्स :

  • और भी अधिक जटिल स्थापित करने के लिए
  • केवल उन मार्गों के लिए अच्छा एसईओ जो आप विशेष उपचार देते हैं
  • सर्वर और क्लाइंट पर सामग्री प्रदान करने के लिए डुप्लिकेटिंग कोड

isomorphic

क्या होगा यदि हम अपने सर्वर के रूप में नोड जेएस का उपयोग करते हैं ताकि हम दोनों छोर पर एक ही जेएस कोड चला सकें ? अब, हमारे पास हमारे सभी मार्ग एकल प्रतिक्रिया-राउटर कॉन्फ़िगरेशन में परिभाषित हैं और हमें अपने रेंडरिंग कोड की नकल करने की आवश्यकता नहीं है। यह बोलने के लिए 'पवित्र कब्र' है। सर्वर उसी तरह का मार्कअप भेजता है, जैसा कि अगर क्लाइंट पर पेज ट्रांजिशन हुआ था, तो हम उसे खत्म कर देंगे। यह समाधान एसईओ के संदर्भ में इष्टतम है।

डाउनसाइड्स :

  • सर्वर को JS चलाने में सक्षम होना चाहिए । मैंने जावा आइकॉन नैशोर्न के साथ प्रयोग किया है लेकिन यह मेरे लिए काम नहीं कर रहा है। व्यवहार में इसका ज्यादातर अर्थ है कि आपको एक नोड जेएस आधारित सर्वर का उपयोग करना चाहिए।
  • कई मुश्किल पर्यावरणीय मुद्दे ( windowसर्वर-साइड आदि का उपयोग करके )
  • तेजी से सीखने की अवस्था

मुझे कौन सा उपयोग करना चाहिए?

वह चुनें जिसे आप दूर कर सकते हैं। व्यक्तिगत रूप से मुझे लगता है कि कैच-ऑल सेट करने के लिए काफी सरल है, इसलिए यह मेरी न्यूनतम होगी। यह सेटअप आपको समय के साथ चीजों में सुधार करने की अनुमति देता है। यदि आप पहले से ही अपने सर्वर प्लेटफॉर्म के रूप में नोड जेएस का उपयोग कर रहे हैं, तो मैं निश्चित रूप से एक आइसोमॉर्फिक ऐप करने की जांच करूंगा। हां यह पहली बार में कठिन है, लेकिन एक बार जब आप इसे लटका लेते हैं तो यह वास्तव में समस्या का एक बहुत ही सुंदर समाधान है।

इसलिए मूल रूप से, मेरे लिए, वह निर्णायक कारक होगा। यदि मेरा सर्वर नोड जेएस पर चलता है, तो मैं आइसोमॉर्फिक जाऊंगा; अन्यथा मैं कैच-ऑल सॉल्यूशन के लिए जाऊंगा और समय बढ़ने और एसईओ आवश्यकताओं के अनुसार इसकी (हाइब्रिड सॉल्यूशन) पर विस्तार करूंगा।

यदि आप रिएक्ट के साथ आइसोमॉर्फिक (जिसे 'यूनिवर्सल' भी कहा जाता है) रेंडर करना सीखना चाहते हैं, तो इस विषय पर कुछ अच्छे ट्यूटोरियल हैं:

इसके अलावा, आपको आरंभ करने के लिए, मैं कुछ स्टार्टर किट देखने की सलाह देता हूं। वह चुनें जो प्रौद्योगिकी स्टैक के लिए आपकी पसंद से मेल खाता है (याद रखें, एमवीसी में रिएक्ट सिर्फ वी है, आपको पूर्ण ऐप बनाने के लिए अधिक सामान की आवश्यकता है)। स्वयं फेसबुक द्वारा प्रकाशित एक को देखने के साथ शुरू करें:

या समुदाय द्वारा कई में से एक को चुनें। अब एक अच्छी साइट है जो उन सभी को अनुक्रमित करने की कोशिश करती है:

मैंने इनसे शुरुआत की:

वर्तमान में मैं सार्वभौमिक प्रतिपादन का एक होम-काढ़ा संस्करण उपयोग कर रहा हूं जो ऊपर के दो स्टार्टर किट से प्रेरित था, लेकिन वे अब पुराने हैं।

आपकी परीक्षा के साथ अच्छी किस्मत!


2
महान पोस्ट Stijn! क्या आप एक आइसोमॉर्फिक रिएक्शन ऐप के लिए स्टार्टर किट के साथ जाने की सलाह देंगे? यदि हां, तो क्या आप एक का उदाहरण दे सकते हैं जिसे आप पसंद करेंगे?
क्रिस

1
@ Paulos3000 यह निर्भर करता है कि आप किस सर्वर का उपयोग कर रहे हैं। मूल रूप से आप इसके लिए एक मार्ग निर्धारित करते हैं /*और इसे अपने HTML पृष्ठ के साथ प्रतिक्रिया देते हैं। यहाँ मुश्किल बात यह है कि यह सुनिश्चित करें कि आप इस मार्ग के साथ .js और .css फ़ाइलों के लिए अनुरोधों को रोकें नहीं।
स्टिजेन डे विट

2
@ पॉलोस 3000 कुछ संबंधित प्रश्नों के लिए यहां देखें: अपाचे / पीएचपी के लिए , एक्सप्रेस / जेएस के लिए , जे 2 ई / जावा के लिए
स्टिजन डे विट

1
नमस्ते, मैं हैश समाधान की कोशिश कर रहा हूं, हालांकि कोई भाग्य नहीं। createMemoryHistory is not a functionत्रुटि हो रही है। एक नज़र मन? stackoverflow.com/questions/45002573/…
लियोन गबन

5
@LeonGaban ऐसा लगता है कि जब से यह उत्तर लिखा गया था, रिएक्ट राउटर ने उनके कार्यान्वयन को बदल दिया। अब उनके पास अलग-अलग इतिहासों के लिए अलग-अलग राउटर उदाहरण हैं और वे पृष्ठभूमि में इतिहास के विन्यास को करते हैं। मूल सिद्धांत अभी भी वही हैं।
स्टिजन डे विट

115

यहां जवाब सभी बेहद मददगार हैं, जो मेरे लिए काम करता है वह मार्गों की अपेक्षा करने के लिए मेरे वेबपैक सर्वर को कॉन्फ़िगर कर रहा था।

devServer: {
   historyApiFallback: true,
   contentBase: './',
   hot: true
},

HistoryApiFallback ने मेरे लिए इस मुद्दे को तय किया है। अब रूटिंग सही तरीके से काम करती है और मैं पेज को सीधे URL में रीफ्रेश कर सकता हूं। अपने नोड सर्वर पर काम के बारे में चिंता करने की कोई जरूरत नहीं है। यह जवाब स्पष्ट रूप से केवल तभी काम करता है जब आप वेबपैक का उपयोग कर रहे हों।

EDIT: अधिक विस्तृत कारण के लिए मेरा उत्तर यहां देखें कि यह क्यों आवश्यक है: https://stackoverflow.com/a/37622953/5217568


16
ध्यान दें कि वेबपैक टीम उत्पादन में देव सर्वर का उपयोग करने के खिलाफ सिफारिश करती है।
स्टिजन डे विट

5
सामान्य विकास उद्देश्यों के लिए यह सबसे अच्छा समाधान है। historyApiFallbackकाफी है। अन्य सभी विकल्पों के लिए, इसे सीएलआई से ध्वज के साथ भी सेट किया जा सकता है --history-api-fallback
मार्को लेज़ेररी

2
@ कुनोक यह नहीं है। यह विकास के लिए एक त्वरित समाधान है लेकिन आपको अभी भी उत्पादन के लिए कुछ करना होगा।
स्टिजन डे विट

contentBase: ': /' कारण आपकी ऐप फाइलें url से एक्सेस की जा सकती हैं
Nezih

85

आप अपनी .htaccessफ़ाइल बदल सकते हैं और इसे सम्मिलित कर सकते हैं :

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-l
  RewriteRule . /index.html [L]
</IfModule>

मैं उपयोग कर रहा हूं react: "^16.12.0"और react-router: "^5.1.2" यह तरीका कैच-ऑल है और शायद आपको शुरू करने का सबसे आसान तरीका है।


3
यह ठीक काम करता है! और सबसे आसान अगर आप अपने ऐप का पुनर्गठन नहीं करना चाहते हैं
mHassin

7
पहली पंक्ति के रूप में रेव्रीटेगाइन को मत भूलना
काई किंग

3
ध्यान दें कि यह उत्तर अपाचे सर्वर पर कॉन्फ़िगर करने की बात कर रहा है। यह एक रिएक्ट ऐप का हिस्सा नहीं है।
कोल्टन हिक्स

मुझे ऊपर दिए गए उत्तर समझ में नहीं आए। किसी भी ट्यूटरोरियल ने नहीं कहा कि मेरे लिंक बिल्कुल भी काम नहीं करेंगे। हालाँकि इस सरल htaccess फ़ाइल ने काम किया। धन्यवाद
थॉमस विलियम्स

यह अगले .js स्थैतिक निर्यात के लिए भी काम करता है। जैसा कि टोमकेट नोड के समान नहीं है, हमें अगले .js स्थैतिक निर्यात के लिए इस अतिरिक्त कॉन्फ़िगरेशन की आवश्यकता है।
गिरि-जीदिगुनता

62

के लिए प्रतिक्रिया रूटर V4 उपयोगकर्ता:

यदि आप अन्य उत्तरों में वर्णित हैश इतिहास तकनीक द्वारा इस समस्या को हल करने का प्रयास करते हैं, तो ध्यान दें

<Router history={hashHistory} >

V4 में काम नहीं करता है, कृपया HashRouterइसके बजाय उपयोग करें :

import { HashRouter } from 'react-router-dom'

<HashRouter>
  <App/>
</HashRouter>

संदर्भ: HashRouter


क्या आप इस बारे में कोई ब्योरा दे सकते हैं कि हश्र रूटर इस मुद्दे को क्यों ठीक करता है? आपके द्वारा दिया गया लिंक मेरे लिए इसे स्पष्ट नहीं करता है। इसके अलावा, क्या मार्ग में हैश को छिपाने का एक तरीका है? मैं BrowserRouter का उपयोग कर रहा था, लेकिन इसके साथ 404 अंक में भाग गया ..
इयान स्मिथ

29

राउटर को दो अलग-अलग तरीकों से बुलाया जा सकता है, यह इस बात पर निर्भर करता है कि नेविगेशन क्लाइंट पर है या सर्वर पर। आपने इसे क्लाइंट-साइड ऑपरेशन के लिए कॉन्फ़िगर किया है। कुंजी पैरामीटर रन विधि के लिए दूसरा एक है , स्थान के लिए दूसरा है।

जब आप रिएक्ट राउटर लिंक घटक का उपयोग करते हैं, तो यह ब्राउज़र नेविगेशन को ब्लॉक करता है और एक क्लाइंट-साइड नेविगेशन करने के लिए ट्रांज़िशनटॉल्स को कॉल करता है। आप HistoryLocation का उपयोग कर रहे हैं, इसलिए यह पता बार में नए URL का अनुकरण करके नेविगेशन के भ्रम को पूरा करने के लिए HTML5 इतिहास एपीआई का उपयोग करता है। यदि आप पुराने ब्राउज़र का उपयोग कर रहे हैं, तो यह काम नहीं करेगा। आपको HashLocation घटक का उपयोग करने की आवश्यकता होगी।

जब आप ताज़ा करते हैं, तो आप सभी प्रतिक्रिया और प्रतिक्रिया रूटर कोड को बायपास कर देते हैं। सर्वर को इसके लिए अनुरोध मिलता है /joblistऔर उसे कुछ वापस करना होगा। सर्वर पर आपको उस पथ को पारित करने की आवश्यकता होती है runजिसे सही दृश्य प्रदान करने के लिए विधि के लिए अनुरोध किया गया था । आप एक ही रूट मैप का उपयोग कर सकते हैं, लेकिन आपको संभवतः एक अलग कॉल की आवश्यकता होगीRouter.run । जैसा कि चार्ल्स बताते हैं, आप इसे संभालने के लिए URL पुनर्लेखन का उपयोग कर सकते हैं। एक अन्य विकल्प सभी अनुरोधों को संभालने और स्थान तर्क के रूप में पथ मान को पारित करने के लिए एक नोड.जेएस सर्वर का उपयोग करना है।

उदाहरण के लिए, यह इस तरह दिख सकता है:

var app = express();

app.get('*', function (req, res) { // This wildcard method handles all requests

    Router.run(routes, req.path, function (Handler, state) {
        var element = React.createElement(Handler);
        var html = React.renderToString(element);
        res.render('main', { content: html });
    });
});

ध्यान दें कि अनुरोध पथ को पारित किया जा रहा है run। ऐसा करने के लिए, आपको एक सर्वर-साइड व्यू इंजन की आवश्यकता होगी जिसे आप प्रदान किए गए HTML को पास कर सकते हैं। renderToStringसर्वर पर रिएक्ट का उपयोग करने और चलाने में कई अन्य विचार हैं । एक बार जब पृष्ठ सर्वर पर प्रदान किया जाता है, जब आपका ऐप क्लाइंट में लोड होता है, तो यह फिर से रेंडर करेगा, सर्वर-साइड को HTML को आवश्यकतानुसार अपडेट करते हुए।


2
क्षमा करें, क्या आप pls को अगला विवरण समझा सकते हैं "जब आप ताज़ा हिट करते हैं, तो आप सभी प्रतिक्रिया और प्रतिक्रिया रूटर कोड को बायपास करते हैं"? क्यों होता है?
VB_

रिएक्ट राउटर का इस्तेमाल आम तौर पर केवल ब्राउज़र के भीतर अलग-अलग 'रास्तों' को संभालने के लिए किया जाता है। ऐसा करने के दो विशिष्ट तरीके हैं: पुरानी शैली हैश पथ और नया इतिहास API। एक ब्राउज़र रिफ्रेश एक सर्वर अनुरोध करेगा, जो आपके क्लाइंट-साइड रिएक्ट राउटर कोड को बायपास करेगा। आपको सर्वर पर पथ को संभालने की आवश्यकता होगी (लेकिन केवल यदि आप इतिहास एपीआई का उपयोग कर रहे हैं)। आप इसके लिए रिएक्टर राउटर का उपयोग कर सकते हैं, लेकिन आपको ऊपर वर्णित के समान कुछ करने की आवश्यकता होगी।
टोड

समझ गया। लेकिन अगर सर्वर गैर-जेएस भाषा पर है (तो जावा को कैसे कहें)?
VB_

2
क्षमा करें ... आपका मतलब है कि आपको "नॉन रूट" रूट को रेंडर करने के लिए एक्सप्रेस सर्वर की आवश्यकता है? मुझे पहले आश्चर्य हुआ था कि आइसोमोर्फिज्म की परिभाषा डेटा कॉन्सेप्ट को अपनी अवधारणा में शामिल नहीं थी (यदि आप डेटा सर्वरसाइड के साथ दृश्य प्रस्तुत करना चाहते हैं तो चीजें काफी जटिल हैं, हालांकि यह एक स्पष्ट एसईओ आवश्यकता होगी - और आइसोमॉर्फ का दावा है)। अब मैं "डब्ल्यूटीएफ रिएक्ट" की तरह हूं, गंभीरता से ... अगर मैं गलत हूं तो मुझे सुधारें, क्या मार्ग को रेंडर करने के लिए एम्बर / कोणीय / रीढ़ की हड्डी को सर्वर की आवश्यकता होती है? मैं वास्तव में मार्गों का उपयोग करने के लिए इस फूला हुआ आवश्यकता को नहीं समझता हूं
बेन

1
क्या इसका मतलब है कि प्रतिक्रिया-राउटर में रिफ्रेश काम नहीं करता है यदि मेरी प्रतिक्रिया अनुप्रयोग आइसोमोर्फिक नहीं है?
मैट

28

अपने index.html में head, निम्नलिखित जोड़ें:

<base href="/">
<!-- This must come before the css and javascripts -->

तब जब webpack देव सर्वर के साथ चल रहा है इस कमांड का उपयोग करें।

webpack-dev-server --mode development --hot --inline --content-base=dist --history-api-fallback

--history-api-fallback महत्वपूर्ण हिस्सा है


यह महान काम किया! किसी भी लिंक पर कुछ और पढ़ने के लिए कैसे आप उस समाधान मिला / मिला?
justDan

1
माफ़ कर दो भाई। परीक्षण और त्रुटि की कोशिश की-सच्ची तकनीक के माध्यम से मिला।
एफे एरारू

यह ध्यान देने योग्य है कि यदि आप एक आधार href का उपयोग कर रहे हैं जो /तब HashRouterकाम नहीं करेगा (यदि आप हैश रूटिंग का उपयोग कर रहे हैं)
Robbie Averill

<आधार href = "/"> टैग ने मेरे लिए किया। इसके लिए धन्यवाद। वेबपैक देव सर्वर बंडल को पथ से खींचने का प्रयास करता रहा / <बंडल> और विफल हो रहा था।
मालिसबाद

27

मैंने अभी-अभी एक वेबसाइट बनाने के लिए create-react-app का उपयोग किया था और यहाँ प्रस्तुत वही मुद्दा था। मैं पैकेज BrowserRoutingसे उपयोग करता हूं react-router-dom। मैं एक नगनेक्स सर्वर पर चल रहा हूं और मेरे लिए इसे हल करना निम्नलिखित में जोड़ रहा था/etc/nginx/yourconfig.conf

location / {
  if (!-e $request_filename){
    rewrite ^(.*)$ /index.html break;
  }
}

.htaccessआप अपाचे चला रहे मामले में निम्नलिखित को जोड़ने से मेल खाती है

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]

यह भी खुद फेसबुक द्वारा सुझाया गया समाधान है और यहां पाया जा सकता है


1
वाह, नग्नेक्स के लिए इस तरह के एक सरल समाधान; एक नए nginx उपयोगकर्ता के रूप में, एक आकर्षण की तरह काम करता है। बस कॉपी-पेस्ट और जाने के लिए अच्छा है। आधिकारिक एफबी प्रलेखन से जोड़ने के लिए +1। जाने के लिए रास्ता।
user3773048

रिकॉर्ड के लिए: मैं nginx और एक कोणीय ऐप के साथ AWS इंस्टेंस का उपयोग कर रहा हूं। यह काम।
डिएगो सरमिनेन्टो

आप मुझे बचा लीजिए। मैं कल से मेरी समस्या को हल करने की कोशिश कर रहा था मैं समाधान के थक गया था, लेकिन मैं असफल रहा। अंत में आपने मुझे इस राउटर मुद्दे को हल करने में मदद की। बहुत बहुत धन्यवाद भाई
शरीफूर रॉबिन

क्या "प्रतिक्रिया" के लिए कुछ अलग आवश्यक है: "^ 16.8.6", "प्रतिक्रिया-राउटर": "^ 5.0.1"? मैंने इन समाधानों (दोनों nginx और अपाचे) की कोशिश की और वे काम नहीं करते हैं।
मार्क ए। टैगियाफेरो

जैसा कि फेसबुक ने इस बारे में अपने प्रलेखन में बदलाव नहीं किया है, मैं केवल यह मान सकता हूं कि प्रक्रिया समान है। मैंने हालांकि थोड़ी देर में इसे आज़माया नहीं है।
एडिन

17

इससे आपकी समस्या दूर हो सकती है

मैं भी उत्पादन मोड में ReactJS आवेदन में एक ही समस्या का सामना करना पड़ा। यहाँ समस्या का 2 समाधान है।

रूटिंग हिस्ट्री को ब्राउजर की जगह "हैशहिस्टर" की जगह राउटिंग हिस्ट्री बदलें

<Router history={hashHistory} >
   <Route path="/home" component={Home} />
   <Route path="/aboutus" component={AboutUs} />
</Router>

अब कमांड का उपयोग करके ऐप बनाएं

sudo npm run build

फिर बिल्ड फ़ोल्डर को अपने var / www / फ़ोल्डर में रखें, अब एप्लिकेशन प्रत्येक और हर यूआरएल में # टैग के साथ ठीक काम कर रहा है। पसंद

लोकलहोस्ट / # / होम लोकलहोस्ट / # / अबाउटस

समाधान 2: बिना # टैग के ब्राउज़र ब्राउज़र का उपयोग करके,

अपने राउटर में अपना इतिहास = {browserHistory} सेट करें, अब sudo npm रन बिल्ड का उपयोग करके इसे बनाएं।

आपको 404 नहीं मिला पेज को हल करने के लिए "कॉन्फ" फाइल बनाने की जरूरत है, इस तरह से कन्फ्यूजन फाइल होनी चाहिए।

नीचे दिए गए आदेशों के अनुसार अपना टर्मिनल खोलें

cd / etc / apache2 / sites-available ls nano sample.conf इसमें नीचे दी गई सामग्री जोड़ें।

<VirtualHost *:80>
    ServerAdmin admin@0.0.0.0
    ServerName 0.0.0.0
    ServerAlias 0.0.0.0
    DocumentRoot /var/www/html/

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
    <Directory "/var/www/html/">
            Options Indexes FollowSymLinks
            AllowOverride all
            Require all granted
    </Directory>
</VirtualHost>

अब आपको निम्न कमांड का उपयोग करके sample.conf फ़ाइल को सक्षम करने की आवश्यकता है

cd /etc/apache2/sites-available
sudo a2ensite sample.conf

तो यह आपको sudo सेवा apache2 रीलोड या रीस्टार्ट का उपयोग करके अपाचे सर्वर को फिर से लोड करने के लिए कहेगा

फिर अपनी लोकलहोस्ट / बिल्ड फोल्डर खोलें और नीचे दी गई सामग्री के साथ .htaccess फ़ाइल जोड़ें।

   RewriteEngine On
   RewriteBase /
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteCond %{REQUEST_FILENAME} !-d
   RewriteCond %{REQUEST_FILENAME} !-l
   RewriteRule ^.*$ / [L,QSA]

अब ऐप सामान्य रूप से काम कर रहा है।

नोट: 0.0.0.0 आईपी को अपने स्थानीय आईपी पते में बदलें।

अगर इस बारे में किसी भी तरह का संदेह कोई टिप्पणी करने के लिए स्वतंत्र महसूस करता है।

मुझे उम्मीद है कि यह दूसरों के लिए उपयोगी है।


पहले समाधान के लिए काम करेंगे "react-router-dom": "^5.1.2", मैं उपयोग कर रहा हूँ<BrowserRouter>
151291

16

यदि आप AWS स्टेटिक S3 होस्टिंग और CloudFront के माध्यम से एक प्रतिक्रिया ऐप होस्ट कर रहे हैं

इस समस्या को CloudFront ने 403 Access Denied संदेश के साथ जवाब देते हुए स्वयं प्रस्तुत किया क्योंकि यह मेरे S3 फ़ोल्डर में मौजूद होने के लिए / कुछ / अन्य / पथ की अपेक्षा करता था, लेकिन यह पथ केवल प्रतिक्रिया-राउटर के साथ React के रूटिंग में आंतरिक रूप से मौजूद है।

समाधान वितरण पृष्ठ त्रुटि नियम स्थापित करना था। CloudFront सेटिंग्स पर जाएं और अपना वितरण चुनें। इसके बाद "त्रुटि पृष्ठ" टैब पर जाएं। "कस्टम त्रुटि प्रतिक्रिया बनाएँ" पर क्लिक करें और 403 के लिए एक प्रविष्टि जोड़ें क्योंकि यह त्रुटि स्थिति कोड हमें मिलता है। प्रतिक्रिया पृष्ठ पथ को /index.html और स्थिति कोड को 200 पर सेट करें। अंतिम परिणाम मुझे इसकी सरलता से चकित करता है। इंडेक्स पेज परोसा जाता है, लेकिन URL ब्राउज़र में संरक्षित होता है, इसलिए एक बार जब एप्लिकेशन लोड हो जाता है, तो यह URL पथ का पता लगाता है और वांछित मार्ग पर नेविगेट करता है।

त्रुटि पृष्ठ 403 नियम


1
मुझे ठीक इसी की आवश्यकता थी। धन्यवाद।
जोनाथन

तो .. आपके सभी यूआरएल काम करते हैं, लेकिन स्थिति कोड 403 लौटाते हैं? यह सही नहीं है। अपेक्षित स्थिति कोड 2xx श्रेणी में होने चाहिए।
स्टिज डे विट

@StijndeWitt मुझे यकीन नहीं है कि आप सही तरीके से समझ रहे हैं। CloudFront सब कुछ संभाल लेगी - क्लाइंट को कोई 403 स्टेटस कोड नहीं दिखेंगे। रि-रूटिंग सर्वर-साइड होता है, इंडेक्स पेज को रेंडर करता है, url को बनाए रखता है, और परिणामस्वरूप सही रूट प्रदान करता है।
th3morg

@ th3morg आह हां मैं अब देख रहा हूं। मैंने याद किया कि यह आपको प्रतिक्रिया स्थिति कोड को 200 के रूप में भरने की भी अनुमति देता है। इसलिए मूल रूप से आप स्टेटस 403 से स्टेटस 200 की मैपिंग कर रहे हैं ... ठीक लग रहा है ... सिवाय इसके कि अगर आपको किसी अन्य कारण के कारण 403 मिलता है, तो शायद आप इसे इस वजह से नहीं देख पाएंगे।
स्टिजन डे विट

1
इसके लिए धन्यवाद @ th3morg क्या यह सेटअप बहु-स्तरीय रास्तों के लिए भी काम करता है? रूट लेवल पर अगर डोमेन / साइनअप, डोमेन / लॉगिन, डोमेन / <डॉक्यूमेंटआईड> जैसे कोई भी रास्ता मेरे लिए बहुत अच्छा है, लेकिन यह डोमेन / डॉक्यूमेंट / <डॉक्यूमेंट> जैसे मल्टी-लेवल पाथ्स के लिए काम नहीं करता है।
13

15

वेबपैक देव सर्वर के पास इसे सक्षम करने का एक विकल्प है। खोलें package.jsonऔर जोड़ें --history-api-fallback। इस समाधान ने मेरे लिए काम किया।

प्रतिक्रिया रूटर-ट्यूटोरियल


3
यह ठीक है, webpack-dev-serverलेकिन मैं उत्पादन के निर्माण के लिए इसे कैसे ठीक करूं?
हुसैन

12

यदि आप IIS पर अपनी प्रतिक्रिया ऐप की मेजबानी कर रहे हैं, तो बस एक web.config फ़ाइल जोड़ें:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Replace">
        <remove statusCode="404" subStatusCode="-1" />
        <error statusCode="404" path="/" responseMode="ExecuteURL" />
    </httpErrors>
  </system.webServer>
</configuration>

यह IIS सर्वर को क्लाइंट के मुख्य पृष्ठ को 404 त्रुटि के बजाय वापस करने और हैश इतिहास का उपयोग करने की आवश्यकता नहीं बताएगा।


धन्यवाद भाई!!!! यही काम है!
थान बाओ

12

इसे इसमें जोड़ें webpack.config.js:

devServer: {
    historyApiFallback: true
}

यह देव के लिए बहुत अच्छा है, लेकिन उत्पादन में मदद नहीं करता है।
केफंक

11

प्रोडक्शन स्टैक: रिएक्ट, रिएक्ट राउटर v4, ब्रॉवर्सर रूटर, एक्सप्रेस, नेग्नेक्स

1) सुंदर यूआरएल के लिए यूजर ब्राउजर राउटर

// app.js

import { BrowserRouter as Router } from 'react-router-dom'

const App = () {
  render() {
    return (
        <Router>
           // your routes here
        </Router>
    )
  }
}

2) सभी अज्ञात अनुरोधों का उपयोग करके index.html जोड़ें /*

// server.js

app.get('/*', function(req, res) {   
  res.sendFile(path.join(__dirname, 'path/to/your/index.html'), function(err) {
    if (err) {
      res.status(500).send(err)
    }
  })
})

3) बंडल वेबपैक के साथ webpack -p

4) चलाएं nodemon server.js याnode server.js

संपादित करें: आप nginx को सर्वर ब्लॉक में इसे संभालने देना चाहते हैं और चरण 2 की अवहेलना कर सकते हैं:

location / {
    try_files $uri /index.html;
}

अपरिभाषित का मार्ग प्राप्त करना
गौतम

@Goutham अपने सर्वर के शीर्ष पर .js फ़ाइल import path from 'pathया तो जोड़ देंconst path = require('path')
इसहाक पाक

चरण 2 (सभी को पकड़ें /*) ने अभी मेरा दिन बचाया है। धन्यवाद! :)
एटलस 7


10

यदि आप Create React App का उपयोग कर रहे हैं:

कई प्रमुख होस्टिंग प्लेटफ़ॉर्म के समाधान के साथ इस समस्या का एक बड़ा चलना है, जिसे आप यहाँ पर रिएक्ट ऐप बनाएं पेज पर पा सकते हैं । उदाहरण के लिए, मैं अपने फ्रंटएंड कोड के लिए React Router v4 और Netlify का उपयोग करता हूं। मेरे सार्वजनिक फ़ोल्डर ("_redirects") में 1 फ़ाइल जोड़ रहा था और उस फ़ाइल में कोड की एक पंक्ति:

/*  /index.html  200

अब मेरी वेबसाइट ठीक तरह से mysite.com/pricing जैसे पथ को ब्राउज़र में दर्ज करते समय या जब कोई ताज़ा करता है तो रेंडर करता है।


7

नीचे दिए गए कोड के साथ सार्वजनिक फ़ोल्डर के अंदर ".htaccess" फ़ाइल को जोड़ने का प्रयास करें।

RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]

RewriteRule ^ /index.html [L]  

धन्यवाद, यह मेरे लिए फेडोरा 28 पर अपाचे के साथ काम किया था। उपर्युक्त नियमों में से कोई भी और न ही CRA पृष्ठ पर किसी ने भी मेरे लिए काम नहीं किया। मैंने उन्हें एक अलग .htaccess फ़ाइल के बजाय वर्चुअल होस्ट सेटअप में जोड़ा।
बोअर्रे

6

यदि आपके पास अपने index.html में कोई कमी है, तो सुनिश्चित करें कि आपकी index.html फ़ाइल में यह आपके पास है:

<script>
  System.config({ baseURL: '/' });
</script>

यह प्रोजेक्ट से प्रोजेक्ट में भिन्न हो सकता है।


2
इसे अपने html में जोड़ें head: <base href = "/">
Efe Ariaroo

4

यदि आप फायरबेस का उपयोग कर रहे हैं, तो आपको यह सुनिश्चित करना होगा कि आपको अपने ऐप के रूट में (होस्टिंग अनुभाग में) अपने फायरबेस में एक फिर से लिखना संपत्ति मिल गई है।

उदाहरण के लिए:

{ 
  "hosting": {
    "rewrites": [{
      "source":"**",
      "destination": "/index.html"
    }]    
  }
}

आशा है कि यह किसी और को हताशा और समय बर्बाद करने से बचाता है।

हैप्पी कोडिंग ...

इस विषय पर आगे पढ़ने:

https://firebase.google.com/docs/hosting/full-config#rewrites

फायरबेस सीएलआई: "सिंगल-पेज ऐप के रूप में कॉन्फ़िगर करें (/ urex.html पर सभी यूआरएल को फिर से लिखें)"


आप एक किंवदंती हैं
Perniferous

4

मैंने अपने एसपीए के लिए प्रतिक्रिया राउटर (अपाचे) के साथ समाधान पाया। बस .htaccess में जोड़ें

<IfModule mod_rewrite.c>

  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_FILENAME} !-l
  RewriteRule . /index.html [L]

</IfModule>

स्रोत: https://gist.github.com/alexsasharegan/173878f9d67055bfef63449fa7136042


3

मैं अभी तक सर्वर साइड रेंडरिंग का उपयोग नहीं कर रहा हूं, लेकिन मैंने ओपी के रूप में उसी समस्या को मारा जहां लिंक ज्यादातर समय ठीक काम करता था, लेकिन जब मेरे पास पैरामीटर था, तो मैं असफल रहा। मैं अपने समाधान का दस्तावेज यहां देखूंगा कि क्या यह किसी की मदद करता है।

मेरे मुख्य jsx में यह शामिल है:

<Route onEnter={requireLogin} path="detail/:id" component={ModelDetail} />

यह पहली मिलान लिंक के लिए ठीक काम करता है लेकिन जब: आईडी में परिवर्तन होता है <Link> उस मॉडल के विवरण पृष्ठ पर नेस्टेड अभिव्यक्ति , तो ब्राउज़र बार में यूआरएल बदल जाता है लेकिन पेज की सामग्री शुरू में लिंक किए गए मॉडल को प्रतिबिंबित करने के लिए नहीं बदली।

परेशानी यह थी कि मैंने props.params.idमॉडल को सेट करने के लिए उपयोग किया था componentDidMount। घटक को बस एक बार माउंट किया जाता है, इसका मतलब है कि पहला मॉडल वह है जो पृष्ठ पर चिपक जाता है और बाद के लिंक प्रॉप्स को बदल देते हैं लेकिन पृष्ठ को अपरिवर्तित छोड़ देते हैं।

मॉडल स्थिति में मॉडल को स्थापित करना componentDidMountऔर दोनों में componentWillReceiveProps(जहां यह अगले प्रॉपर पर आधारित है) समस्या को हल करता है और वांछित मॉडल को प्रतिबिंबित करने के लिए पृष्ठ सामग्री में परिवर्तन होता है।


1
यदि आप कभी भी सर्वर-साइड रेंडरिंग के लिए प्रयास करना चाहते हैं, तो घटक कंस्ट्रक्टर (जिसमें भी एक्सेस है props) का उपयोग करना बेहतर होगा componentDidMount। क्योंकि componentDidMountकेवल ब्राउज़र में कहा जाता है। यह उद्देश्य डोम के साथ सामान करना है, जैसे कि घटना श्रोताओं को bodyइत्यादि से जोड़ना जो आप में नहीं कर सकते render
स्टिज डे विट

3

यह विषय थोड़ा पुराना और सुलझा हुआ है, लेकिन मैं आपको एक सरल, स्पष्ट और बेहतर समाधान सुझाना चाहूंगा। यदि आप वेब सर्वर का उपयोग करते हैं तो यह काम करता है।

प्रत्येक वेब सर्वर में http 404 के मामले में उपयोगकर्ता को एक त्रुटि पृष्ठ पर पुनर्निर्देशित करने की क्षमता है। इस समस्या को हल करने के लिए आपको उपयोगकर्ता को सूचकांक पृष्ठ पर पुनर्निर्देशित करने की आवश्यकता है।

यदि आप जावा बेस सर्वर (टॉमकैट या किसी जावा एप्लिकेशन सर्वर) का उपयोग करते हैं, तो समाधान निम्नलिखित हो सकता है:

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <!-- WELCOME FILE LIST -->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <!-- ERROR PAGES DEFINITION -->
    <error-page>
        <error-code>404</error-code>
        <location>/index.jsp</location>
    </error-page>

</web-app>

उदाहरण:

  • Http://example.com/about प्राप्त करें
  • वेब सर्वर http 404 फेंकता है क्योंकि यह पेज सर्वर साइड पर मौजूद नहीं है
  • त्रुटि पृष्ठ कॉन्फ़िगरेशन उस सर्वर को बताता है जो उपयोगकर्ता को index.jsp पृष्ठ वापस भेजता है
  • तब जेएस बाकी काम क्लेयन साइड पर करेगा क्योंकि क्लाइंट साइड पर यूआरएल अभी भी http://example.com/about है

यह है, कोई और अधिक जादू की जरूरत है :)


यह कमाल था! मैं वाइल्डफ्लाइ 10.1 सर्वर का उपयोग कर रहा हूं और इस अपडेट को अपनी web.xml फ़ाइल में बनाया है, सिवाय इसके कि मेरे पास सिर्फ '/' के लिए स्थान निर्धारित था। ऐसा इसलिए हुआ क्योंकि मेरे रिएक्शन कोड में मैंने ब्राउजर हिस्ट्री को इस तरह इस्तेमाल किया:const browserHistory = useRouterHistory(createHistory)({ basename: '/<appname>' });
चक एल

1
क्या आप सुनिश्चित हैं कि यह SEO को प्रभावित नहीं करता है? आप उन पृष्ठों को 404 का दर्जा दे रहे हैं जो वास्तव में मौजूद हैं। उपयोगकर्ता को कभी भी इसका एहसास नहीं हो सकता है, लेकिन बॉट्स बहुत अधिक ध्यान देते हैं, वास्तव में इतना, कि वे आपके पेज को खुरचेंगे नहीं।
सुभारब

3

यदि आप बैकएंड में एक्सप्रेस या कुछ अन्य ढांचे का उपयोग कर रहे हैं, तो आप नीचे दिए गए समान कॉन्फ़िगरेशन को जोड़ सकते हैं और कॉन्फ़िगरेशन में वेबपैक सार्वजनिक पथ की जांच कर सकते हैं, यह ब्राउज़र लोडर का उपयोग करने पर भी पुनः लोड होने पर ठीक काम करना चाहिए।

expressApp.get('/*', (request, response) => {
    response.sendFile(path.join(__dirname, '../public/index.html'));
});

यह सबसे सरल उपाय है। ध्यान दें कि यह मार्ग किसी भी अन्य मार्गों के बाद जाना चाहिए क्योंकि यह एक कैच है
dcsan

3

रिफ्रेश करने पर या सीधे URL पर कॉल करने पर "GET / URL" त्रुटि को ठीक नहीं किया जा सकता है।

दिए गए लिंक को इस तरह से जोड़ने के लिए अपने webpack.config.js को कॉन्फ़िगर करें ।

module.exports = {
  entry: './app/index.js',
  output: {
       path: path.join(__dirname, '/bundle'),
       filename: 'index_bundle.js',
       publicPath: '/'
  },

2

जैसा कि मैं उपयोग कर रहा हूँ .नेट कोर MVC कुछ इस तरह से मुझे मदद मिली:

    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            var url = Request.Path + Request.QueryString;
            return App(url);
        }

        [Route("App")]
        public IActionResult App(string url)
        {
            return View("/wwwroot/app/build/index.html");
        }
   }

मूल रूप से एमवीसी पक्ष में, मेल नहीं खाने वाले सभी मार्ग Home/Indexइसमें निर्दिष्ट किए गए अनुसार गिर जाएंगे startup.cs। इसके अंदर Indexमूल अनुरोध url प्राप्त करना और जहां जरूरत हो वहां से गुजरना संभव है।

startup.cs

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");

            routes.MapSpaFallbackRoute(
                name: "spa-fallback",
                defaults: new { controller = "Home", action = "Index" });
        });

अगर वेब एप एप से अलग हो जाता है तो आप इसे कैसे संभालेंगे?
दिनमान

@ dayanrr91 अगर आपके प्रोजेक्ट में वेब एपी है, तो आपको वैसे भी सर्वर साइड रूटिंग की जरूरत नहीं होगी। और आपके प्रतिक्रिया-राउटर का मानना ​​है कि मुझे यूआरएल पढ़ना चाहिए और उचित मार्ग करना चाहिए। कुछ भी इसे अवरुद्ध नहीं करना चाहिए
एलेनूर

आपकी टिप्पणी की बहुत सराहना की गई है, लेकिन फिर मेरे पास एक सवाल है, मैंने अभी HashRouter को जोड़ा है, लेकिन अब जब मैं किसी भी URL को मैन्युअल रूप से दर्ज करता हूं, तो यह मेरे घर के घटक को मेरे घर पर अनुप्रेषित करने के बजाय पुनर्निर्देशित करेगा और फिर उस घटक को जो मैं करने की कोशिश कर रहा था में हो रही है, वहाँ के लिए कोई workaround है?
दिनमान

@ dayanrr91 वास्तव में कोई विचार नहीं है, कभी भी हैशटर की कोशिश नहीं की है, लेकिन मुझे लगता है कि आपके कोड के साथ कुछ करना चाहिए। जिस तरह से हैशाउंटर काम करता है, वह ब्राउजर के समान होना चाहिए। इसके अलावा, मैं सिर्फ यहाँ इस सैंडबॉक्स में परीक्षण किया है, यह ठीक codeandbox.io/s/25okp1mny काम करता है , url 25okp1mny.codesandbox.io/#/roster/5
Elnoor

2

यदि आप IIS में होस्ट कर रहे हैं; इसे मेरे वेबकॉन्फ़ में जोड़ने से मेरी समस्या हल हो गई

<httpErrors errorMode="Custom" defaultResponseMode="ExecuteURL">
    <remove statusCode="500" subStatusCode="100" />
    <remove statusCode="500" subStatusCode="-1" />
    <remove statusCode="404" subStatusCode="-1" />
    <error statusCode="404" path="/" responseMode="ExecuteURL" />
    <error statusCode="500" prefixLanguageFilePath="" path="/error_500.asp" responseMode="ExecuteURL" />
    <error statusCode="500" subStatusCode="100" path="/error_500.asp" responseMode="ExecuteURL" />
</httpErrors>

आप किसी अन्य सर्वर के लिए समान कॉन्फ़िगरेशन बना सकते हैं


1

मामले में, कोई भी यहां लारवेल के साथ रिएक्ट जेएस एसपीए पर समाधान की तलाश कर रहा है। स्वीकृत जवाब इस तरह की समस्याएं क्यों होती हैं, इसका सबसे अच्छा विवरण है। जैसा कि पहले ही समझाया गया है कि आपको क्लाइंट साइड और सर्वर साइड दोनों को कॉन्फ़िगर करना होगा। अपने ब्लेड टेम्पलेट में, js बंडल फ़ाइल शामिल करें URL facade, इस तरह का उपयोग करना सुनिश्चित करें

<script src="{{ URL::to('js/user/spa.js') }}"></script>

अपने मार्गों में, यह सुनिश्चित करें कि इसे मुख्य समापन बिंदु पर जोड़ें जहां ब्लेड टेम्पलेट है। उदाहरण के लिए,

Route::get('/setting-alerts', function () {
   return view('user.set-alerts');
});

ब्लेड टेम्पलेट के लिए मुख्य समापन बिंदु ऊपर है। अब एक वैकल्पिक मार्ग भी जोड़ें,

Route::get('/setting-alerts/{spa?}', function () {
  return view('user.set-alerts');
});

समस्या यह है कि पहले ब्लेड टेम्पलेट लोड किया जाता है, फिर प्रतिक्रिया राउटर। इसलिए, जब आप लोड कर रहे हैं '/setting-alerts', तो यह html और js लोड करता है। लेकिन जब आप लोड करते हैं '/setting-alerts/about', तो यह पहले सर्वर साइड पर लोड होता है। चूंकि सर्वर की ओर, इस स्थान पर कुछ भी नहीं है, यह रिटर्न नहीं मिला। जब आपके पास वह वैकल्पिक राउटर होता है, तो वह उसी पेज को लोड करता है और राउटर को भी लोड किया जाता है, फिर रियेक्टर लोड करने का निर्णय लेता है कि किस घटक को दिखाना है। उम्मीद है की यह मदद करेगा।


क्या एक सटीक यूआरआई को सर्वर पर लोड करना संभव है फिर सर्वर रिएक्ट के लिए पुनर्निर्देशित करता है? उदाहरण के लिए, जब मैं लोड करता हूं /user/{userID}, तो मुझे केवल एक सार्वभौमिक /userHTML दृश्य वापस करने की आवश्यकता होती है , आईडी लाएं और AJAX या axios का उपयोग करके इसे कॉल करें। क्या यह करना मुमकिन है? क्या वे एसईओ के अनुकूल हैं?
रियूजो

1

उन लोगों के लिए जो IIS 10 का उपयोग कर रहे हैं, यह वही है जो आपको यह अधिकार बनाने के लिए करना चाहिए। सुनिश्चित करें कि आप इस के साथ BrowserHistory का उपयोग कर रहे हैं। संदर्भ के लिए मैं रूटिंग के लिए कोड दूंगा, लेकिन यह क्या मायने रखता है, नीचे दिए गए घटक कोड के बाद अगला कदम क्या मायने रखता है:

class App extends Component {
    render() {
        return (
            <Router history={browserHistory}>
                <div>
                    <Root>
                        <Switch>
                            <Route exact path={"/"} component={Home} />    
                            <Route path={"/home"} component={Home} />
                            <Route path={"/createnewproject"} component={CreateNewProject} />
                            <Route path={"/projects"} component={Projects} />
                            <Route path="*" component={NotFoundRoute} />
                        </Switch>
                    </Root>
                </div>
            </Router>
        )
    }
}
render (<App />, window.document.getElementById("app"));

चूंकि समस्या आईआईएस क्लाइंट ब्राउज़रों से अनुरोध प्राप्त करता है, यह URL की व्याख्या करेगा जैसे कि यह एक पृष्ठ के लिए पूछ रहा है, फिर 404 पृष्ठ लौटाता है क्योंकि कोई उपलब्ध पृष्ठ नहीं है। निम्न कार्य करें:

  1. IIS खोलें
  2. सर्वर का विस्तार करें फिर साइट्स फ़ोल्डर खोलें
  3. वेबसाइट / एप्लिकेशन पर क्लिक करें
  4. त्रुटि पृष्ठों पर जाएं
  5. सूची में 404 त्रुटि स्थिति आइटम खोलें
  6. "त्रुटि प्रतिक्रिया में स्थिर फ़ाइल से सामग्री डालें" विकल्प के बजाय, इसे "इस साइट पर एक URL निष्पादित करें" और URL में "/" स्लैश मान जोड़ें।

और यह अब ठीक काम करेगा।

यहाँ छवि विवरण दर्ज करें यहाँ छवि विवरण दर्ज करें

मुझे उम्मीद है यह मदद करेगा। :-)


1

मैं WebPack का उपयोग कर रहा हूं, मेरे पास एक ही समस्या थी समाधान => आपके server.js फ़ाइल में

const express = require('express');
const app = express();

app.use(express.static(path.resolve(__dirname, '../dist')));
  app.get('*', function (req, res) {
    res.sendFile(path.resolve(__dirname, '../dist/index.html'));
    // res.end();
  });

मेरे आवेदन को ताज़ा करने के बाद प्रस्तुत क्यों नहीं किया जाता है?


यह मेरे लिए यह किया है! शुरू में मेरे पास res.sendFile (path.JOIN (publicPath, "index.html")) था; मैंने ऊपर दिए गए उदाहरण की तरह "जुड़ाव" को "हल" में बदल दिया: res.sendFile (path.resolve ("./ dist", "index.html")); मैं भी __dirname के साथ खेल रहा था, लेकिन वास्तव में इसे समझ नहीं पाया या काम कर रहा था इसलिए मैंने मैन्युअल रूप से "//dist "में कॉपी किया क्योंकि यह वह जगह है जहाँ से मेरी index.html से सेवा ली जाती है। मैंने इसे भी पहले की तरह घोषित किया: app.use (express.static ("./ dist"));
लॉजिकप्लेयर

1

Redux केHashRouter साथ मेरे लिए भी काम करना , बस प्रतिस्थापित करना:

import {
  Router //replace Router
} from "react-router-dom";

ReactDOM.render(
    <LocaleProvider locale={enUS}>
    <Provider store={Store}>
        <Router history={history}> //replace here saying Router
            <Layout/>
        </Router>
    </Provider>
</LocaleProvider>, document.getElementById("app"));
registerServiceWorker();

सेवा:

import {
  HashRouter //replaced with HashRouter
} from "react-router-dom";

ReactDOM.render(
    <LocaleProvider locale={enUS}>
    <Provider store={Store}>
        <HashRouter history={history}> //replaced with HashRouter
            <Layout/>
        </HashRouter>
    </Provider>
</LocaleProvider>, document.getElementById("app"));
registerServiceWorker();

0

मुझे भी यही समस्या थी और इस समाधान ने हमारे लिए काम किया ।।

पृष्ठभूमि:

हम एक ही सर्वर पर कई ऐप्स होस्ट कर रहे हैं। जब हम रिफ्रेश करेंगे तो सर्वर को यह समझ नहीं आएगा कि उस विशेष ऐप के लिए डिस्टर्ब फोल्डर में हमारे इंडेक्स को कहां देखें। उपरोक्त लिंक आपको हमारे लिए काम करने के लिए ले जाएगा ... आशा है कि यह मदद करता है, क्योंकि हमने अपनी जरूरतों के लिए एक समाधान निकालने में काफी समय बिताया है।

हम प्रयोग कर रहे हैं:

package.json

"dependencies": {
"babel-polyfill": "^6.23.0",
"ejs": "^2.5.6",
"express": "^4.15.2",
"prop-types": "^15.5.6",
"react": "^15.5.4",
"react-dom": "^15.5.4",
"react-redux": "^5.0.4",
"react-router": "^3.0.2",
"react-router-redux": "^4.0.8",
"redux": "^3.6.0",
"redux-persist": "^4.6.0",
"redux-thunk": "^2.2.0",
"webpack": "^2.4.1"
}

my webpack.config.js

webpack.config.js

/* eslint-disable */
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const babelPolyfill = require('babel-polyfill');
const HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
  template: __dirname + '/app/views/index.html',
  filename: 'index.html',
  inject: 'body'
});

module.exports = {
  entry: [
    'babel-polyfill', './app/index.js'
  ],
  output: {
    path: __dirname + '/dist/your_app_name_here',
    filename: 'index_bundle.js'
  },
  module: {
    rules: [{
      test: /\.js$/,
      loader: 'babel-loader',
      query : {
          presets : ["env", "react", "stage-1"]
      },
      exclude: /node_modules/
    }]
  },
  plugins: [HTMLWebpackPluginConfig]
}

मेरे index.js

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import Routes from './Routes'
import { Provider } from 'react-redux'
import { createHistory } from 'history'
import { useRouterHistory } from 'react-router'
import configureStore from './store/configureStore'
import { syncHistoryWithStore } from 'react-router-redux'
import { persistStore } from 'redux-persist'

const store = configureStore();

const browserHistory = useRouterHistory(createHistory) ({
  basename: '/your_app_name_here'
})
const history = syncHistoryWithStore(browserHistory, store)

persistStore(store, {blacklist: ['routing']}, () => {
  console.log('rehydration complete')
})
// persistStore(store).purge()


ReactDOM.render(
    <Provider store={store}>
      <div>
        <Routes history={history} />
      </div>
    </Provider>,
  document.getElementById('mount')
)

मेरे app.js

var express = require('express');
var app = express();

app.use(express.static(__dirname + '/dist'));
// app.use(express.static(__dirname + '/app/assets'));
app.set('views', __dirname + '/dist/your_app_name_here');
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');

app.get('/*', function (req, res) {
    res.render('index');
});

app.listen(8081, function () {
  console.log('MD listening on port 8081!');
});

0

मुझे इसे संभालने का यह तरीका पसंद है। जोड़ने का प्रयास करें: इस समस्या से छुटकारा पाने के लिए सर्वर साइड पर yourSPAPageRoute / *

मैं इस दृष्टिकोण के साथ गया, क्योंकि यहां तक ​​कि देशी एचटीएमएल 5 इतिहास एपीआई पेज रिफ्रेश (जहां तक ​​मुझे पता है) पर सही पुनर्निर्देशन का समर्थन नहीं करता है।

नोट: चयनित उत्तर ने पहले ही इसे संबोधित कर दिया है लेकिन मैं और अधिक विशिष्ट होने की कोशिश कर रहा हूं।

एक्सप्रेस मार्ग

टेस्ट - इतिहास एपीआई परीक्षण किया गया और बस इसे साझा करना चाहता था।

आशा है ये मदद करेगा।

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