جاوااسکریپت - آدرسهای React-router هنگام بازخوانی یا نوشتن دستی کار نمیکنند


من از React-router استفاده میکنم و وقتی روی دکمههای لینک کلیک میکنم خوب کار میکند، اما وقتی وبسایتم را تازهسازی میکنم آنچه میخواهم بارگذاری نمیشود.

برای مثال، من در localhost/joblist هستم و همه چیز خوب است زیرا با فشار دادن یک لینک به اینجا رسیدم. اما اگر صفحه وب را تازه کنم، دریافت میکنم:

Cannot GET /joblist

به طور پیشفرض، اینطور کار نمیکرد. ابتدا آدرس URL من به صورت localhost/#/ و localhost/#/joblist بود و کاملاً درست کار میکرد. اما من این نوع URL را دوست نداشتم، بنابراین برای حذف آن #، نوشتم:

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

این مشکل با localhost/ رخ نمیدهد، این یکی همیشه چیزی که میخواهم را برمیگرداند.

این برنامه تکصفحهای است، بنابراین /joblist نیازی ندارد که چیزی از هیچ سروری بپرسد.

کل روتر من.

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

پاسخ شماره ۱

سمت سرور در مقابل سمت کلاینت

اولین نکته بزرگ برای درک این موضوع این است که اکنون دو مکانی وجود دارد که URL در آنجا تفسیر میشود، در حالی که قبلاً تنها یک مکان در «روزهای قدیم» وجود داشت. در گذشته، وقتی زندگی ساده بود، یک کاربر درخواستی برای http://example.com/about به سرور ارسال میکرد، سرور بخش مسیر URL را بررسی میکرد، تشخیص میداد که کاربر صفحه درباره را درخواست کرده و سپس آن صفحه را باز میگرداند.

با روتینگ سمت مشتری، که همان چیزی است که React Router فراهم میکند، اوضاع سادهتر نیست. ابتدا، کلاینت هیچ کد جاوااسکریپتی بارگذاری نکرده است. بنابراین اولین درخواست همیشه به سرور ارسال میشود. سرور سپس صفحهای را بازمیگرداند که شامل تگهای اسکریپت لازم برای بارگذاری React و React Router و غیره است. فقط وقتی آن اسکریپتها بارگذاری شدند، فاز دوم شروع میشود. در فاز دوم، وقتی کاربر روی لینک ناوبری «درباره ما» کلیک میکند، به عنوان مثال، URL فقط بهصورت محلی به http://example.com/about تغییر میکند (که با API تاریخ امکانپذیر است)، اما هیچ درخواستی به سرور ارسال نمیشود. در عوض، React Router کار خود را در سمت کلاینت انجام میدهد، تعیین میکند کدام نمای React باید رندر شود و آن را رندر میکند. فرض کنید صفحه درباره شما نیازی به انجام هیچ فراخوانی REST ندارد، در این صورت کار تمام شده است. شما از خانه به درباره ما منتقل شدهاید بدون اینکه هیچ درخواست سروری ارسال شده باشد.

پس اساساً وقتی روی یک لینک کلیک میکنید، جاوااسکریپتی اجرا میشود که URL در نوار آدرس را دستکاری میکند، بدون اینکه صفحه تازه شود، که این به نوبه خود باعث میشود React Router یک انتقال صفحه را در سمت کلاینت انجام دهد.

اما اکنون تصور کنید چه اتفاقی میافتد اگر URL را در نوار آدرس کپی و به دوستتان ایمیل کنید. دوست شما هنوز وبسایت شما را بارگذاری نکرده است. به عبارت دیگر، او هنوز در فاز 1 است. هیچ React Router ای روی دستگاه او اجرا نشده است. بنابراین مرورگر او یک درخواست سرور به http://example.com/about ارسال خواهد کرد.

و اینجاست که مشکل شما شروع میشود. تا الان، میتوانستید با قرار دادن یک HTML ایستا در روت وب سرور خود کار را راه بیندازید. اما این باعث میشد که برای تمام URL های دیگر خطای ۴۰۴ نمایش داده شود وقتی از سمت سرور درخواست میشوند. همان URL ها در سمت مشتری به خوبی کار میکنند، زیرا در آنجا React Router مسیریابی را برای شما انجام میدهد، اما در سمت سرور شکست میخورند مگر اینکه سرور خود را طوری تنظیم کنید که آنها را بشناسد.

ترکیب مسیریابی سمت سرور و سمت کلاینت

اگر میخواهید آدرس http://example.com/about هم در سمت سرور و هم در سمت کلاینت کار کند، باید مسیرهایی برای آن در هر دو سمت سرور و کلاینت تنظیم کنید. منطقی است، درست است؟

و اینجاست که انتخابهای شما آغاز میشود. راهحلها از کنار زدن کامل مشکل، از طریق یک مسیر عمومی که HTML بوتاسترپ را بازمیگرداند، تا روش ایزومورفیک کامل که در آن هم سرور و هم کلاینت همان کد جاوااسکریپت را اجرا میکنند، متغیر است.

کاملاً دور زدن مشکل: تاریخچه هش

با استفاده از تاریخچه هش، به جای تاریخچه مرورگر، آدرس اینترنتی شما برای صفحه درباره ممکن است چیزی شبیه این باشد: http://example.com/#/about

قسمت بعد از علامت هش (#) به سرور ارسال نمیشود. بنابراین سرور فقط http://example.com/ را میبیند و صفحه شاخص را همانطور که انتظار میرود ارسال میکند. React Router قسمت #/about را برمیدارد و صفحه صحیح را نمایش میدهد.

معایب:

  • آدرسهای اینترنتی «زشت»
  • رندر سمت سرور با این روش ممکن نیست. تا آنجا که به بهینهسازی موتور جستجو (SEO) مربوط میشود، وبسایت شما از یک صفحه تشکیل شده است که تقریباً هیچ محتوایی در آن ندارد.

همهچیز

با این روش، از تاریخچه مرورگر استفاده میcکنید، اما تنها یک کنترلر کلی روی سرور راهcاندازی میcکنید که /* را به index.html میcفرستد، که عملاً همان شرایطی را به شما میcدهد که با سابقه هش داشتید. با این حال، شما URL های تمیزی دارید و بعداً می توانید این تنظیمات را بدون نیاز به باطل کردن همه نشانک های کاربران خود بهبود بخشید.

معایب:

  • راهاندازی پیچیدهتر
  • هنوز سئوی خوبی ندارد

هیبرید

در رویکرد ترکیبی، شما سناریوی همهگیر را با افزودن اسکریپتهای خاص برای مسیرهای خاص گسترش میدهید. میتوانید برخی اسکریپتهای ساده PHP بسازید تا مهمترین صفحات سایت خود را با محتوای شامل بازگردانند، بنابراین Googlebot حداقل میتواند ببیند که در صفحه شما چه چیزی وجود دارد.

معایب:

  • هنوز هم پیچیدهتر برای راهاندازی
  • تنها سئو خوب برای آن مسیرهایی که شما درمان ویژهای میدهید
  • تکرار کد برای رندر کردن محتوا در سرور و کلاینت

همشکل

اگر از Node.js به عنوان سرور خود استفاده کنیم، چه میشود تا بتوانیم همان کد جاوااسکریپت را در هر دو طرف اجرا کنیم؟ حالا، تمام مسیرهای خود را در یک پیکربندی react-router تعریف کردهایم و نیازی به تکرار کد رندرینگ خود نداریم. این به نوعی «جام مقدس» است. سرور دقیقاً همان مارکآپی را ارسال میکند که اگر انتقال صفحه روی کلاینت اتفاق میافتاد، به دست میآوردیم. این راهحل از نظر سئو بهینه است.

معایب:

  • سرور باید بتواند جاوااسکریپت را اجرا کند. من با جاوا همراه با ناشورن آزمایش کردهام، اما برای من کار نمیکند. در عمل، این به معنای آن است که شما عمدتاً باید از یک سرور مبتنی بر Node.js استفاده کنید.
  • بسیاری از مسائل پیچیده محیطی (استفاده از window در سمت سرور و غیره)
  • منحنی یادگیری تند

کدام را باید استفاده کنم؟

یکی را انتخاب کنید که بتوانید از پسش برآیید. شخصاً، فکر میکنم تنظیم یک catch-all به اندازه کافی ساده است، بنابراین این حداقل مورد من خواهد بود. این تنظیم به شما اجازه میدهد که به مرور زمان روی چیزها پیشرفت کنید. اگر در حال حاضر از Node.js به عنوان پلتفرم سرور خود استفاده میکنید، قطعاً توصیه میکنم بررسی کنید که یک اپلیکیشن ایزومورفیک بسازید. بله، ابتدا سخت است، اما وقتی که روی آن تسلط پیدا کنید، در واقع یک راه حل بسیار زیبا برای مشکل است.

پس اصولاً، برای من، این عامل تصمیمگیرنده خواهد بود. اگر سرور من روی Node.js اجرا شود، من از ایزومورفیک استفاده میکنم؛ در غیر این صورت، به سراغ راهحل جامع میروم و فقط آن را توسعه میدهم (راهحل ترکیبی) همانطور که زمان میگذرد و نیازمندیهای SEO ایجاب میکند.

اگر میخواهید بیشتر درباره رندرینگ ایزومورفیک (که به آن «جهانی» نیز گفته میشود) با React بیاموزید، چند آموزش خوب در این موضوع وجود دارد:

  • با برنامههای ایزومورفیک به آینده واکنش نشان دهید
  • درد و شادی ساخت برنامههای ایزومورفیک در ReactJS
  • چگونه Node + React JavaScript ایزومورفیک را پیادهسازی کنیم و چرا اهمیت دارد

همچنین، برای اینکه شروع کنید، پیشنهاد میکنم به بعضی کیتهای شروع نگاه کنید. یکی را انتخاب کنید که با انتخابهای شما برای پشته فناوری مطابقت داشته باشد (به یاد داشته باشید، React فقط V در MVC است، برای ساخت یک برنامه کامل به چیزهای بیشتری نیاز دارید). با نگاه کردن به کیتی که خود فیسبوک منتشر کرده، شروع کنید:

  • ایجاد برنامه ریاکت

یا یکی از بسیاریها که توسط جامعه ساخته شده را انتخاب کنید. اکنون یک سایت خوب وجود دارد که سعی میکند همه آنها را فهرست کند:

  • پروژه شروعکننده React کامل خود را انتخاب کنید

من با اینها شروع کردم:

  • کیت شروع ایزومورفیک ریکت
  • نمونه داغ جهانی ریداکس ریکت

در حال حاضر، من از نسخهای خانگی از رندرینگ یونیورسال استفاده میکنم که از دو کیت شروع فوق الهام گرفته شده است، اما اکنون آنها قدیمی شدهاند.

موفق باشی در مأموریتت!

پاسخ شماره ۲

اگر از آپاچی به عنوان سرور وب خود استفاده میکنید، میتوانید این را در فایل .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" استفاده میکنم. این روش همهکاره است و احتمالاً آسانترین راه برای شروع کار شماست.

پاسخ شماره ۳

پاسخهای اینجا همگی بسیار مفید هستند. پیکربندی سرور Webpack من برای انتظار مسیرها برای من کارساز بود.

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

ویژگی historyApiFallback همان چیزی است که این مشکل را برای من حل کرد. حالا مسیریابی به درستی کار میکند و میتوانم صفحه را تازهسازی کنم یا آدرس URL را مستقیماً وارد کنم. نیازی نیست نگران راهحلهای موقتی روی سرور Node.js خود باشید. این پاسخ واضح است که فقط در صورتی کار میکند که از Webpack استفاده کنید.

برای دلیلی دقیقتر مبنی بر اینکه چرا این لازم است، پاسخ من به React-router 2.0 browserHistory هنگام تازهسازی کار نمیکند را ببینید.

پاسخ شماره ۴

برای کاربران React Router V4:

اگر سعی کنید این مشکل را با استفاده از تکنیک تاریخچه هش که در پاسخهای دیگر ذکر شده است حل کنید، توجه داشته باشید که

<Router history={hashHistory} >

در V4 کار نمیکند. لطفاً به جای آن از HashRouter استفاده کنید:

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

<HashRouter>
  <App/>
</HashRouter>

ارجاع: HashRouter

پاسخ شماره ۵

من همین حالا از Create React App برای ساخت یک وبسایت استفاده کردم و همان مشکل مطرح شده در اینجا را داشتم.

من از BrowserRouting از بسته react-router-dom استفاده میکنم. من روی سرور Nginx اجرا میکنم و افزودن موارد زیر به /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]

این نیز به نظر میرسد راهحلی باشد که خود فیسبوک پیشنهاد کرده و میتوان آن را اینجا یافت.

پاسخ شماره ۶

در فایل index.html خود در قسمت head، موارد زیر را اضافه کنید:

<base href="/">
<!-- This must come before the CSS and JavaScript code -->

سپس، هنگام اجرا با سرور توسعه Webpack، از این دستور استفاده کنید.

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

--history-api-fallback بخش مهم است

پاسخ شماره ۷

اگر از Create React App استفاده میکنید:

راهنمای بسیار خوبی در این مورد وجود دارد که راهحلهایی برای بسیاری از پلتفرمهای بزرگ میزبانی ارائه میدهد و میتوانید آن را اینجا در صفحه Create React App پیدا کنید. برای مثال، من از React Router نسخه ۴ و Netlify برای کد فرانتاند خود استفاده میکنم. تمام کاری که باید میکردم این بود که یک فایل به پوشه عمومی خود اضافه کنم ("_redirects") و یک خط کد در آن فایل بنویسم:

/*  /index.html  200

حالا وبسایت من مسیرهایی مانند mysite.com/pricing را به درستی هنگام وارد کردن در مرورگر یا وقتی کسی صفحه را دوباره بارگذاری میکند نمایش میدهد.

پاسخ شماره ۸

اگر برنامه React خود را روی 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 صفحه اصلی را به مشتری بازگرداند و نیازی به استفاده از تاریخچه هش نیست.

پاسخ شماره ۹

روتر میتواند به دو روش مختلف فراخوانی شود، بسته به اینکه ناوبری در سمت مشتری یا در سمت سرور انجام شود. شما آن را برای عملکرد سمت مشتری پیکربندی کردهاید. پارامتر کلیدی پارامتر دوم متد run است، یعنی location.

وقتی از کامپوننت Link در React Router استفاده میکنید، مرورگر را از ناوبری معمولی باز میدارد و برای انجام ناوبری سمت کلاینت، تابع transitionTo را فراخوانی میکند. شما از HistoryLocation استفاده میکنید، بنابراین API تاریخچه HTML5 را برای تکمیل توهم ناوبری با شبیهسازی URL جدید در نوار آدرس استفاده میکند. اگر از مرورگرهای قدیمی استفاده میکنید، این کار پاسخگو نخواهد بود. شما نیاز دارید از کامپوننت HashLocation استفاده کنید.

وقتی روی تازهسازی کلیک میکنید، همهی کدهای React و React Router را دور میزنید. سرور درخواست /joblist را دریافت میکند و باید چیزی بازگرداند. در سرور، شما نیاز دارید مسیری که درخواست شده را به متد run منتقل کنید تا نمای درست رندر شود. میتوانید از همان نقشه مسیر استفاده کنید، اما احتمالاً به فراخوانی متفاوت Router.run نیاز خواهید داشت. همانطور که چارلز اشاره میکند، میتوانید از بازنویسی URL برای مدیریت این موضوع استفاده کنید. گزینه دیگری این است که از یک سرور Node.js استفاده کنید تا همه درخواستها را مدیریت کرده و مقدار مسیر را به عنوان آرگومان location منتقل کنید.

برای مثال، در Express.js ممکن است اینگونه به نظر برسد:

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 و اجرای React در سرور وجود دارد. هنگامی که صفحه در سرور رندر شد، وقتی برنامه شما در کلاینت بارگذاری میشود، دوباره رندر خواهد شد و HTML رندر شده سمت سرور را در صورت نیاز بهروزرسانی میکند.

پاسخ شماره ۱۰

اگر یک برنامه React را از طریق میزبانی استاتیک S3 و CloudFront در AWS میزبانی میکنید

این مشکل با پاسخ CloudFront با پیام 403 Access Denied ظاهر شد، زیرا انتظار داشت /some/other/path در پوشه S3 من وجود داشته باشد، اما آن مسیر فقط به صورت داخلی در مسیریابی React با React Router وجود دارد.

راه حل این بود که یک قانون صفحات خطا برای توزیع تنظیم کنیم. به تنظیمات CloudFront بروید و توزیع خود را انتخاب کنید. سپس به برگه «صفحات خطا» بروید. روی «ایجاد پاسخ خطای سفارشی» کلیک کنید و برای 403 یک ورودی اضافه کنید چون این کد وضعیت خطایی است که دریافت میکنیم.

مسیر صفحه پاسخ را روی /index.html و کد وضعیت را روی ۲۰۰ تنظیم کنید.

نتیجه نهایی با سادگی خود مرا شگفتزده میکند. صفحه شاخص ارائه میشود، اما URL در مرورگر حفظ میشود، بنابراین وقتی برنامه React بارگذاری میشود، مسیر URL را تشخیص میدهد و به مسیر مورد نظر هدایت میشود.

صفحات خطا ۴۰۳ قانون

پاسخ شماره ۱۱

این میتواند مشکل شما را حل کند.

من نیز در برنامه React در حالت تولید با همان مشکل مواجه شدم. در اینجا دو راه حل برای این مشکل آورده شده است.

راه حل 1. تاریخچه مسیریابی را به «hashHistory» تغییر دهید به جای browserHistory در محل

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

حالا برنامه را با استفاده از دستور بسازید

sudo npm run build

سپس پوشه build را در پوشه var/www/ خود قرار دهید. حالا برنامه با اضافه شدن # در هر URL به خوبی کار میکند. مانند

localhost/#/home
localhost/#/aboutus

راه حل ۲: بدون تگ # با استفاده از browserHistory،

تاریخچه خود را در مسیریاب خود برابر با {browserHistory} قرار دهید. حالا با استفاده از sudo npm run build آن را بسازید.

شما نیاز دارید فایل «conf» را برای رفع صفحه 404 پیدا نشد ایجاد کنید. فایل conf باید به این شکل باشد.

ترمینال خود را باز کنید و دستورات زیر را تایپ کنید

cd /etc/apache2/sites-available
ls
nano sample.conf

محتوای زیر را به آن اضافه کنید.

<VirtualHost *:80>
    ServerAdmin [email 
    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 service apache2 reload or restart

سپس پوشه localhost/build خود را باز کنید و فایل .htaccess را با محتوای زیر اضافه کنید.

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

حالا برنامه بهطور عادی کار میکند.

توجه: آدرس آیپی 0.0.0.0 را به آدرس آیپی محلی خود تغییر دهید.

پاسخ شماره ۱۲

این را به webpack.config.js اضافه کنید:

devServer: {
    historyApiFallback: true
}

پاسخ شماره ۱۳

سرور توسعه Webpack یک گزینه برای فعال کردن این دارد. فایل package.json را باز کنید و --history-api-fallback را اضافه کنید. این راهحل برای من مفید بود.

آموزش ریاکت روتر

پاسخ شماره ۱۴

پشته تولید: ریاکت، ریاکت روتِر نسخه ۴، برازرروتر، اکسپرسجیاس، انگینایکس

  1. از User BrowserRouter برای URL های زیبا استفاده کنید

    فایل 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 با webpack -p

  4. اجرای nodemon server.js یا node server.js

ممکن است بخواهید اجازه دهید nginx این کار را در بلوک سرور انجام دهد و مرحله ۲ را نادیده بگیرید:

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

پاسخ شماره ۱۵

سعی کنید یک فایل ".htaccess" درون پوشه public اضافه کنید با کد زیر.

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

RewriteRule ^ /index.html [L]

پاسخ شماره ۱۶

اگر شما از nginx برای میزبانی استفاده میکنید و به یک راهحل سریع نیاز دارید...

خط زیر را در پیکربندی nginx خود داخل بلوک location اضافه کنید:

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

پاسخ شماره ۱۷

اگر از Firebase استفاده میکنید، تنها کاری که باید انجام دهید این است که مطمئن شوید یک ویژگی rewrites در فایل firebase.json خود در ریشه برنامه خود (در بخش میزبانی) دارید.

به عنوان مثال:

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

مطالعهٔ بیشتر در این موضوع:

  • پیکربندی بازنویسیها

  • Firebase CLI: "پیکربندی به عنوان یک برنامه تک صفحه ای (بازنویسی همه URL ها در /index.html)"

پاسخ شماره ۱۸

برای کسانی که از 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"));

از آنجایی که مشکل این است که IIS درخواستها را از مرورگرهای کلاینت دریافت میکند، URL را به گونهای تفسیر میکند که گویی در حال درخواست یک صفحه است و سپس صفحه 404 را بازمیگرداند زیرا هیچ صفحهای در دسترس نیست. کارهای زیر را انجام دهید:

  1. باز کردن IIS
  2. گسترش Server، و سپس پوشه Sites را باز کنید
  3. روی وبسایت/برنامه کلیک کنید
  4. به صفحات خطا بروید
  5. آیتم وضعیت خطای ۴۰۴ را در فهرست باز کنید
  6. به جای گزینه «درج محتوا از فایل ثابت در پاسخ خطا»، آن را به «اجرای یک URL در این سایت» تغییر دهید و مقدار «/» را به URL اضافه کنید.

و حالا بهخوبی کار خواهد کرد.