چطور خطای ۴۰۴ بعد از انتشار وبسایت یا اپ را برطرف کنیم
اگر اپتان روی سیستم محلی درست کار میکند ولی بعد از دیپلوی صفحهها ۴۰۴ میدهند، رایجترین علت نبودن مسیریابی single-page app (SPA) است: سرور دنبال فایلی به نام /dashboard میگردد که وجود ندارد، چون آن مسیر فقط در جاوااسکریپت وجود دارد. راهحل یک قاعدهی بازگشت است که برای مسیرهای اپ، index.html را سرو کند. علتهای دیگر: فایلهای گمشده از خروجی بیلد، مسیرهای حساس به حروف، تفاوت در اسلش انتهایی، base path اشتباه و API هایی که هرگز دیپلوی نشدهاند.
ابتدا دقیقاً مشخص کنید کدام نشانی ۴۰۴ میدهد و چطور به آن رسیدهاید. الگو مستقیم به علت اشاره میکند.
گام ۱: الگو را پیدا کنید
| آنچه میبینید | علت محتمل | برو به |
|---|---|---|
| صفحهی اصلی کار میکند؛ کلیک روی لینکها کار میکند؛ اما رفرش یا باز کردن لینک عمیق ۴۰۴ میدهد | نبودن بازگشت SPA | گام ۲ |
| همهی صفحهها، حتی صفحهی اصلی، ۴۰۴ میدهند | پوشهی اشتباه منتشر شده یا بیلد دیپلوی نشده | گام ۳ |
| صفحهها بارگذاری میشوند، اما تصاویر، فونتها یا اسکریپتها ۴۰۴ میدهند | فایلها در بیلد نیستند یا مسیرها اشتباهاند | گام ۴ |
با /about/ کار میکند، با /about نه (یا برعکس) | مدیریت اسلش انتهایی | گام ۵ |
/About خطا میدهد اما /about کار میکند | سرور حساس به حروف بزرگ و کوچک | گام ۴ |
صفحه بارگذاری میشود، اما درخواستهای داده به /api/... ۴۰۴ میدهند | API دیپلوی یا مسیریابی نشده | گام ۶ |
| نشانیهای قدیمی از سایت قبلی ۴۰۴ میدهند | ریدایرکتهای گمشده | گام ۷ |
| فقط روی دامنهی اختصاصی | تنظیمات DNS یا دامنه | گام ۸ |
برای دیدن کد وضعیت واقعی، ابزارهای توسعهدهنده را باز کنید (راستکلیک → Inspect)، به تب Network بروید، صفحه را رفرش کنید و وضعیت اولین درخواست را ببینید.
گام ۲: بازگشت SPA را اضافه کنید
این کلاسیکترین مورد است. در یک اپ تکصفحهای React، Vue یا Svelte، سرور فقط چند فایل واقعی دارد: index.html و مقداری JavaScript و CSS. مسیرهایی مثل /dashboard یا /projects/42 را روتری در مرورگر مدیریت میکند.
- کلیک روی لینک کار میکند: روتر نشانی را عوض میکند و صفحهی جدید را بدون درخواست از سرور نشان میدهد.
- رفرش یا باز کردن مستقیم لینک خراب میشود: مرورگر از سرور
/dashboardرا میخواهد، سرور چنین فایلی ندارد و ۴۰۴ برمیگرداند.
راهحل قاعدهای است که میگوید: اگر درخواست با یک فایل واقعی نمیخواند، index.html را با وضعیت ۲۰۰ سرو کن و بگذار روتر کار را بر عهده بگیرد. نحوهی اضافه کردنش به میزبان بستگی دارد (مستندات فعلی میزبان را بررسی کنید، چون جزئیات تغییر میکنند):
| میزبان | قاعدهی بازگشت معمول |
|---|---|
| Netlify | فایل _redirects در پوشهی منتشرشده با خط /* /index.html 200 |
| Vercel | یک rewrite در vercel.json از همهی مسیرها به /index.html (presetهای فریمورک اغلب این را خودشان انجام میدهند) |
| Cloudflare Pages | وقتی فایل 404.html در سطح بالا نباشد، بازگشت به سبک SPA را بهطور پیشفرض سرو میکند |
| Nginx | try_files $uri $uri/ /index.html; در بلوک location / |
| Apache | یک قاعدهی rewrite در .htaccess که درخواستهای غیرفایلی را به index.html بفرستد |
| GitHub Pages | ریرایت سمت سرور ندارد؛ راهحلهای رایج، مسیریابی با هش یا یک 404.html است که ریدایرکت میکند |
مطمئن شوید قاعده فایلهای واقعی را نمیبلعد: درخواست برای /assets/app.js باید هنوز فایل JavaScript را برگرداند. اگر بهجایش index.html برگردد، یک صفحهی خالی با خطای «Failed to load module script» میبینید. چطور صفحهی سفید خالی را برطرف کنیم را ببینید.
همچنین به روتر یک مسیر catch-all بدهید تا نشانیهایی که با هیچ صفحهای نمیخوانند، بهجای چیزی نامرئی، یک صفحهی «صفحه پیدا نشد» دوستانه نشان دهند.
اگر نمیتوانید تنظیمات سرور را تغییر دهید، مسیریابی با هش (نشانیهایی مثل /#/dashboard) مشکل را دور میزند، چون بخشی که بعد از # میآید هرگز به سرور فرستاده نمیشود. این یک راهحل موقت است، نه انتخاب اول: نشانیها زشتترند و برای موتورهای جستجو دوستانه نیستند.
فریمورکهایی که صفحات را روی سرور رندر یا در زمان بیلد تولید میکنند (Next.js، Astro و مشابه آنها) معمولاً برای هر صفحه فایل یا مسیر سروری واقعی دارند، بنابراین این مشکل خاص در آنها کمتر پیش میآید. معادل آن در آنها، صفحهای است که در زمان بیلد تولید نشده.
گام ۳: بررسی کنید واقعاً چه دیپلوی شده
اگر همهچیز ۴۰۴ میدهد، احتمالاً سرور اپ ساختهشدهی شما را سرو نمیکند.
- پوشهی درست. میزبان باید خروجی بیلد را منتشر کند (معمولاً
distبرای Vite،buildبرای Create React App،outبرای خروجی استاتیک Next.js)، نه ریشهی پروژه. - بیلد اجرا شده است. لاگ دیپلوی را بخوانید. اگر بیلد شکست خورده، میزبان ممکن است هیچچیز یا نسخهی قدیمی را دیپلوی کرده باشد.
index.htmlدر سطح بالای پوشهی منتشرشده است، نه در یک زیرپوشه.- base path درست است. اگر اپ از
example.com/app/سرو میشود، باید با همان base بیلد شده باشد (baseدر Vite،basenameدر React Router)، وگرنه همهی مسیرها و داراییها گم میشوند.
گام ۴: فایلهای گمشده و مسیرهای اشتباه را درست کنید
وقتی صفحهها بارگذاری میشوند ولی داراییها ۴۰۴ میدهند:
- حساسیت به حروف بزرگ و کوچک. macOS و Windows معمولاً
Logo.pngوlogo.pngرا یک فایل میدانند. اکثر سرورهای لینوکسی اینطور نیستند. هر ارجاع را دقیقاً با نام واقعی فایل یکی کنید. - فایلهای بیرون از بیلد. در Vite، فایلهای داخل
public/همانطور کپی میشوند و از ریشه ارجاع داده میشوند (/logo.png). فایلهایی که در کد import میشوند داخل بیلد قرار میگیرند. فایلی که جای دیگری در پروژه است ممکن است اصلاً دیپلوی نشود. - مسیرهای نسبی.
images/photo.jpgنسبت به نشانی فعلی حل میشود، پس روی/blog/post-1خراب میشود. از/images/photo.jpgاستفاده کنید. - فایلهای آپلودشده روی دیسک محلی. اگر آپلودهای کاربران در پوشهی خود سرور ذخیره شده باشد، با دیپلوی نسخهی جدید از بین میروند. از فضای ذخیرهسازی مناسب استفاده کنید.
گام ۵: اسلش انتهایی را یکدست کنید
/about و /about/ دو نشانی متفاوتاند. میزبانها در اضافه یا حذف کردن اسلش فرق دارند و ناهماهنگی با لینکها یا روترتان میتواند ۴۰۴ یا حلقهی ریدایرکت بسازد. یک سبک را انتخاب کنید، لینکها را با همان بسازید و میزبان را طوری تنظیم کنید که شکل دیگر را به شکل انتخابی ریدایرکت کند. این یکدستی به موتورهای جستجو هم کمک میکند که وگرنه ممکن است دو نسخه از هر صفحه ببینند.
گام ۶: API هایی که ۴۰۴ میدهند را درست کنید
اگر صفحه بارگذاری میشود ولی تب Network درخواستهای /api/... با ۴۰۴ نشان میدهد:
- بکاِند دیپلوی نشده است. یک میزبان استاتیک فقط فایل سرو میکند؛ بکاِند باید جایی اجرا شود.
- مسیر در محیط عملیاتی متفاوت مسیریابی میشود. در توسعه، یک پروکسی ممکن است
/apiرا به یک سرور جدا فرستاده باشد. در محیط عملیاتی، میزبان به یک rewrite معادل نیاز دارد، یا فرانتاِند باید نشانی واقعی API را صدا بزند. - بازگشت SPA آن را گرفته است. اگر درخواست API با وضعیت ۲۰۰ و محتوای
index.htmlبرگردد، یعنی قاعدهی بازگشت خیلی گسترده است./api/*را از آن مستثنا کنید.
درخواستهای اپ منتشرشده به /api/orders ۴۰۴ میدهند، ولی در پیشنمایش کار میکنند. مسیریابی /api را در پیشنمایش و اپ منتشرشده مقایسه کنید و فرانتاِند منتشرشده را طوری تنظیم کنید که به بکاِند همانطور برسد.
گام ۷: نشانیهای قدیمی را ریدایرکت کنید
اگر از سایت دیگری جابهجا شدهاید یا ساختار را تغییر دادهاید، نشانیهای قدیمی که مردم و موتورهای جستجو هنوز استفاده میکنند ۴۰۴ میدهند. برای هر نشانی قدیمی یک ریدایرکت ۳۰۱ (دائمی) به محل جدیدش اضافه کنید. فهرستی نگه دارید و بعد از راهاندازی، نمونهای را آزمایش کنید. راهنمای ما دربارهی انتقال وبسایت وردپرس نشان میدهد چطور این فهرست را بسازید.
گام ۸: دامنه را بررسی کنید
اگر اپ در نشانی میزبان کار میکند ولی روی دامنهی اختصاصی ۴۰۴ میدهد، ممکن است دامنه به پروژهی اشتباهی اشاره کند، یا میزبان هنوز دامنه را به سایتتان وصل نکرده است. رکوردهای DNS و تنظیمات دامنهی میزبان را بررسی کنید. چطور دامنهی اختصاصی را وصل کنیم را ببینید.
صفحهی ۴۰۴ واقعی را مفید کنید
برخی ۴۰۴ها درستاند: کسی نشانی را اشتباه تایپ کرده است. آن صفحه را مفید کنید:
- یک پیام کوتاه و لینکی به صفحهی اصلی و بخشهای کلیدی
- یک جعبهی جستجو، اگر سایت جستجو دارد
- همان هدر و ناوبری بقیهی سایت
هر جا تنظیماتتان اجازه میدهد، برای صفحههایی که وجود ندارند یک کد وضعیت ۴۰۴ واقعی برگردانید. پیام «پیدا نشد» با وضعیت ۲۰۰ همان چیزی است که موتورهای جستجو soft 404 مینامند و میتواند زمان خزش را هدر دهد و ایندکسگذاری را گیج کند.
اشتباهات رایج
- آزمایش فقط با کلیک. همیشه با چسباندن نشانیهای عمیق در یک تب جدید و رفرش آزمایش کنید.
- بازگشتی که همهچیز را میگیرد. داراییها و مسیرهای API،
index.htmlبرمیگردانند که باعث صفحههای خالی و خطاهای گیجکنندهی API میشود. - حساسیت حروف بزرگ و کوچک که فقط روی سرور خراب میشود.
- دیپلوی پوشهی سورس بهجای خروجی بیلد.
- بازسازی نشانیها بدون ریدایرکت. هر لینک قدیمی تبدیل به ۴۰۴ میشود.
۴۰۴ها در Mythex
در Mythex از داخل فضای کار منتشر میکنید و فرانتاِندهای استاتیک بهصورت سایت استاتیک دیپلوی میشوند. اگر یک صفحهی منتشرشده ۴۰۴ داد، نشانی دقیق، اینکه موقع رفرش رخ میدهد یا موقع کلیک، و آنچه تب Network نشان میدهد را به عامل بدهید و بخواهید مسیریابی را بررسی کند. بعد از اصلاح دوباره منتشر کنید، چون اپ زنده تا وقتی دوباره منتشر نکنید یک نسخهی ثابت است. اگر اخیراً پروژه را تغییر دادهاید و سایت زنده قدیمی به نظر میرسد، دوباره منتشر کنید و با Hard refresh بررسی کنید. اگر بیلد شکست خورد، از Fix with AI در گفتوگوی انتشار استفاده کنید. نحوهی انتشار و عیبیابی انتشار را در مستندات ببینید و راهنمای ما دربارهی عیبیابی یک اپ ساختهشده با هوش مصنوعی را.
فهرست بررسی ۴۰۴
- دقیقاً مشخص کردهام کدام نشانیها ۴۰۴ میدهند و آیا با کلیک، رفرش یا هر دو
- بازگشت SPA برای مسیرهای اپ،
index.htmlرا با وضعیت ۲۰۰ سرو میکند - بازگشت فایلهای واقعی و
/api/*را مستثنا میکند - روتر یک مسیر catch-all «پیدا نشد» دارد
- پوشهی خروجی بیلد همان چیزی است که منتشر میشود، و بیلد موفق بوده است
- base path با جایی که اپ سرو میشود یکی است
- حروف بزرگ و کوچک نام فایلها با همهی ارجاعها یکی است
- مسیر داراییها با
/شروع میشود - سبک اسلش انتهایی یکدست است
- API ها در محیط عملیاتی دیپلوی و مسیریابی شدهاند
- ریدایرکتهای ۳۰۱ برای نشانیهای قدیمی
- لینکهای عمیق با چسباندنشان در یک تب جدید آزمایش شدهاند
پرسشها
چرا وقتی یک صفحه را در اپ React رفرش میکنم، ۴۰۴ میگیرم؟
در یک اپ تکصفحهای، مسیرهایی مثل /dashboard فقط در جاوااسکریپت وجود دارند. کلیک روی لینک کار میکند چون روتر در مرورگر آن را مدیریت میکند، اما رفرش از سرور فایلی به نام /dashboard میخواهد که وجود ندارد. راهحل یک قاعدهی بازگشت است که برای مسیرهای اپ، index.html را سرو کند.
چطور بازگشت SPA را روی Netlify، Vercel یا Nginx اضافه کنم؟
در Netlify یک فایل _redirects با خط /* /index.html 200 بسازید. در Vercel یک rewrite در vercel.json بنویسید که همهی مسیرها را به /index.html بفرستد. در Nginx از try_files $uri $uri/ /index.html; در بلوک location استفاده کنید. مستندات میزبان را بررسی کنید، چون قواعد تغییر میکنند.
چرا تصاویر یا فایلهایم بعد از انتشار ۴۰۴ میدهند؟
معمولاً فایل در خروجی بیلد نیست، یا حروف بزرگ و کوچک مسیر با نام واقعی فایل یکی نیست (سرورها اغلب حساساند در حالی که لپتاپ شما نیست)، یا مسیر نسبی است درحالیکه باید با / شروع شود.
آیا صفحهی گمشده باید کد وضعیت واقعی ۴۰۴ برگرداند؟
بله. یک صفحهی راهنمای «پیدا نشد» مفید نشان دهید، اما اگر تنظیمات شما اجازه میدهد با کد وضعیت ۴۰۴. موتورهای جستجو پیامی از نوع «پیدا نشد» را که با وضعیت ۲۰۰ برگردد، soft 404 میدانند؛ این کار زمان خزش را هدر میدهد و ایندکسگذاری را گیج میکند.