صرف نظر و مشاهده محتوا

۳۱ شهریور، ساعت 18 الی 20 | در همایش «تحول دیجیتال کسب‌وکار با Odoo ERP» با مسیر سیستم‌سازی یکپارچه تا هوشمندسازی کسب‌وکار آشنا شوید. همین حالا ثبت نام کنید.

ثبت‌نام رایگان
۰ ۰ : ۰ ۰ : ۰ ۰ : ۰ ۰

خوش آمدید!

این تالار گفتگو در خصوص محصولات و خدمات تسهیل گستر و نرم افزار سازمان یار ( قدرت گرفته از Odoo ERP ) ایجاد شده است.

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

این سؤال پرچم‌دار شده است
1 پاسخ
58 بازدید

یک مشکل آزاردهنده دارم که هرچه در لوکال تست می‌کنم، API بدون مشکل کار می‌کند؛ اما وقتی پروژه را روی سرور می‌برم، درخواست‌ها fail می‌شوند یا پاسخ درست برنمی‌گردد.

در محیط لوکال همه چیز خوب است:

  • درخواست‌ها ارسال می‌شوند
  • پاسخ API برمی‌گردد
  • فرانت و بک‌اند با هم ارتباط دارند

اما روی سرور یکی از این اتفاق‌ها می‌افتد:

  • درخواست اصلاً ارسال نمی‌شود
  • خطای CORS می‌گیرم
  • پاسخ 404 یا 500 می‌گیرم
  • در مرورگر خطای Mixed Content دیده می‌شود
  • روی سرور مسیر API پیدا نمی‌شود
  • هدرها یا کوکی‌ها درست کار نمی‌کنند
  • در Postman جواب می‌گیرد ولی در فرانت نه

سؤالم این است که چرا یک API در لوکال کار می‌کند اما روی سرور نه؟ از کجا باید عیب‌یابی را شروع کنم و چه مواردی را باید بررسی کنم؟

تصویر پروفایل
صرف نظر
مؤلف

این مشکل بسیار رایج است و تقریباً همیشه به تفاوت بین محیط لوکال و محیط production برمی‌گردد. در لوکال، خیلی از خطاها پنهان می‌مانند یا تنظیمات به‌صورت ساده‌تر عمل می‌کنند، اما روی سرور همه چیز واقعی‌تر، محدودتر و حساس‌تر می‌شود.

اگر API در لوکال کار می‌کند ولی روی سرور نه، معمولاً مشکل از یکی از این موارد است:

  • آدرس API اشتباه تنظیم شده
  • CORS درست پیکربندی نشده
  • متغیرهای محیطی فرق دارند
  • HTTPS و HTTP با هم قاطی شده‌اند
  • مسیرها یا Rewrite Rules روی سرور ناقص‌اند
  • فایروال یا تنظیمات امنیتی سرور درخواست را می‌بندد
  • کوکی، سشن یا احراز هویت روی دامنه اصلی درست عمل نمی‌کند
  • تفاوت بین build توسعه و build production وجود دارد

در ادامه مهم‌ترین علت‌ها را بررسی می‌کنیم.

1. آدرس API در لوکال و سرور یکی نیست

در پروژه‌های فرانت‌اند معمولاً آدرس API به‌صورت متغیر محیطی تعریف می‌شود. ممکن است در لوکال این مقدار درست باشد، اما روی سرور اشتباه تنظیم شده باشد.

مثلاً در لوکال:

VITE_API_URL=http://localhost:8000/api

اما روی سرور باید چیزی مثل این باشد.

VITE_API_URL=https://api.example.com/api

اگر این مقدار روی سرور هنوز به localhost اشاره کند، طبیعی است که مرورگر نتواند به API واقعی برسد.

راه‌حل
  • فایل‌های .env را در لوکال و production جدا کنید.
  • بعد از تغییر ENV حتماً پروژه را دوباره build کنید.
  • مطمئن شوید آدرس نهایی درست به backend production اشاره می‌کند.
2. مشکل CORS

یکی از شایع‌ترین علت‌ها همین است.

در لوکال، شاید فرانت‌اند روی این آدرس اجرا شود:

http://localhost:5173

و بک‌اند روی این آدرس:

http://localhost:8000

در production اما فرانت‌اند روی دامنه اصلی است و بک‌اند روی دامنه یا ساب‌دامین دیگری. اگر backend اجازه ندهد که origin فرانت به آن درخواست بزند، مرورگر درخواست را مسدود می‌کند.

مثال خطای CORS
Access to fetch at 'https://api.example.com' from origin 'https://example.com'
has been blocked by CORS policy
راه‌حل

در backend باید originهای مجاز را تعریف کنید، مثلاً:

app.use(cors({ origin: ['https://example.com', 'https://www.example.com'], credentials: true }))

اگر از cookie یا session استفاده می‌کنید، باید credentials هم درست تنظیم شود.

3. تفاوت HTTP و HTTPS

در لوکال ممکن است همه‌چیز با HTTP اجرا شود و مشکلی دیده نشود، اما روی سرور سایت با HTTPS بالا آمده است.

اگر فرانت‌اند HTTPS باشد ولی API را با HTTP صدا بزنید، مرورگر ممکن است درخواست را به‌عنوان Mixed Content مسدود کند.

مثال مشکل‌دار
https://example.com

فرانت از اینجا API را می‌زند:

http://api.example.com
راه‌حل
  • فرانت و بک‌اند را هر دو روی HTTPS قرار دهید.
  • همه URLهای API را به نسخه امن تغییر دهید.
  • اگر پشت reverse proxy هستید، تنظیمات SSL را کامل بررسی کنید.
4. مسیرها روی سرور متفاوت هستند

گاهی API روی لوکال به‌خاطر تنظیمات dev server یا proxy خوب کار می‌کند، اما روی production مسیرها درست rewrite نشده‌اند.

مثلاً در Vue یا Vite، ممکن است در لوکال از proxy استفاده کرده باشید:

server: { proxy: { '/api': 'http://localhost:8000' } }

این proxy فقط برای توسعه است و روی سرور production وجود ندارد.

راه‌حل
  • مطمئن شوید فرانت‌اند در production مستقیماً آدرس واقعی backend را می‌زند.
  • مسیرهای backend را در Nginx یا Apache بررسی کنید.
  • اگر SPA دارید، قوانین rewrite برای routeها و API تداخل نداشته باشند.
5. مشکل با Nginx یا Apache

روی سرور، وب‌سرور نقش مهمی دارد. ممکن است درخواست API اصلاً به backend نرسد، چون تنظیمات Nginx یا Apache اشتباه است.

مثال مشکلات رایج
  • مسیر /api به backend proxy نشده
  • ریدایرکت اشتباه باعث loop شده
  • فایل‌های static با routeهای API تداخل دارند
  • تنظیمات location در Nginx اولویت نادرست دارند
راه‌حل

لاگ‌های Nginx یا Apache را بررسی کنید. برای مثال در Nginx باید مطمئن شوید مسیر API به backend منتقل می‌شود:

location /api/ {
    proxy_pass http://127.0.0.1:8000/;
}

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

6. فایروال یا محدودیت سرور

ممکن است پورت backend روی سرور باز نباشد یا فایروال اجازه دسترسی ندهد.

در لوکال، همه چیز روی سیستم خودتان است و محدودیت خاصی ندارید، اما روی سرور:

  • پورت backend بسته است
  • سرویس اجرا نشده
  • systemd یا PM2 کرش کرده
  • سرویس فقط روی localhost bind شده و از بیرون قابل دسترسی نیست
راه‌حل
  • وضعیت سرویس backend را بررسی کنید
  • لاگ‌های سرور را ببینید
  • مطمئن شوید backend روی آدرس درست listen می‌کند
  • بررسی کنید پورت موردنیاز باز باشد
7. کوکی، سشن و احراز هویت روی سرور خراب شده‌اند

گاهی API از نظر فنی کار می‌کند، اما احراز هویت fail می‌شود. این موضوع مخصوصاً در پروژه‌هایی که از cookie-based auth یا session استفاده می‌کنند رایج است.

مشکل ممکن است از این موارد باشد:

  • SameSite درست تنظیم نشده
  • Secure برای کوکی روی HTTPS فعال نشده
  • Domain کوکی اشتباه است
  • credentials در فرانت ارسال نمی‌شود
  • CORS برای کوکی‌ها فعال نشده
نمونه

اگر فرانت روی دامنه‌ای جدا باشد و بخواهید کوکی را ارسال کنید:

fetch(url, { credentials: 'include' })

و در backend هم باید CORS و cookie config با آن هماهنگ باشد.

8. تفاوت build توسعه و production

بعضی باگ‌ها فقط در production ظاهر می‌شوند چون build نهایی با نسخه development فرق دارد.

مثلاً:

  • minify شدن کد
  • tree shaking
  • تفاوت در environment variables
  • cache شدن فایل‌ها
  • اجرای متفاوت router یا lazy loading
راه‌حل
  • پروژه را دقیقاً با همان تنظیمات production روی لوکال build و تست کنید.
  • از npm run build یا معادل آن استفاده کنید.
  • خروجی production را محلی اجرا کنید تا همان رفتار واقعی را ببینید.
9. پاسخ در Postman می‌آید ولی در فرانت نه

این یکی خیلی مهم است.

اگر API در Postman جواب می‌دهد، ولی در مرورگر نه، معمولاً مشکل از backend خام نیست؛ بلکه از محدودیت‌های مرورگر است، مثل:

  • CORS
  • کوکی و credentials
  • Mixed Content
  • هدرهای امنیتی
  • preflight request

Postman قوانین مرورگر را اجرا نمی‌کند، پس ممکن است مشکلی را نشان ندهد که در واقع در مرورگر وجود دارد.

نتیجه

Postman ابزار خوبی برای تست API است، اما اگر فرانت‌اند نمی‌تواند API را صدا بزند، باید حتماً تست مرورگر و Network Tab را هم بررسی کنید.

10. لاگ‌ها را نادیده نگیرید

خیلی وقت‌ها مشکل در لاگ‌ها مشخص است اما بررسی نمی‌شود.

در فرانت‌اند:
  • Console مرورگر
  • Network Tab
  • Status code
  • Response headers
  • Request payload
در بک‌اند:
  • لاگ اپلیکیشن
  • لاگ Nginx / Apache
  • لاگ فایروال
  • لاگ سرویس‌دهنده مثل PM2, Docker, systemd

اگر درخواست اصلاً به backend نرسد، در لاگ backend چیزی نمی‌بینید. این خودش یک نشانه مهم است که مشکل قبل از backend رخ داده است.

روش سریع عیب‌یابی

برای پیدا کردن علت، این مسیر را بروید:

  1. آدرس API را در production دقیق بررسی کنید.
  2. درخواست را در مرورگر و Network Tab ببینید.
  3. خطای CORS یا Mixed Content را چک کنید.
  4. ببینید درخواست اصلاً به backend می‌رسد یا نه.
  5. لاگ سرور و وب‌سرور را بررسی کنید.
  6. وضعیت HTTPS و دامنه‌ها را چک کنید.
  7. ENVهای production را با لوکال مقایسه کنید.
  8. اگر auth دارید، تنظیمات cookie و credentials را بررسی کنید.
جمع‌بندی

اگر API در لوکال کار می‌کند ولی روی سرور نه، مشکل معمولاً از خود API نیست، بلکه از تفاوت محیط‌هاست.

مهم‌ترین علت‌ها این‌ها هستند:

  • آدرس اشتباه API
  • CORS
  • HTTP/HTTPS
  • تنظیمات Nginx یا Apache
  • فایروال
  • کوکی و session
  • تفاوت ENV
  • build production

بهترین روش این است که از Network Tab مرورگر شروع کنید و قدم‌به‌قدم مشخص کنید درخواست در کدام مرحله می‌افتد: قبل از ارسال، در شبکه، در وب‌سرور، یا داخل backend.

تصویر پروفایل
صرف نظر

پاسخ شما

سعی کنید یک پاسخ اساسی ارائه کنید. اگر می‌خواهید در مورد سؤال یا پاسخ نظر دهید، کافیست از ابزار نظردهی استفاده کنید. به خاطر داشته باشید که همیشه می‌توانید پاسخ‌های خود را اصلاح کنید - نیازی نیست یک سؤال را دوبار پاسخ دهید. همچنین رأی دادن را فراموش نکنید - این کار کمک می‌کند بهترین سؤال و جواب‌ها را انتخاب کنیم!

پست‌های مرتبط پاسخ‌ها بازدید فعالیت
1
مرداد 26
87
1
مرداد 26
138
1
مرداد 26
167
1
مرداد 26
310
1
مرداد 26
778