Zen Eddin Allaham نشر منذ 5 ساعة أرسل تقرير نشر منذ 5 ساعة عندي مشروع React + Express.js ورفعت مجلد خادم على render و تم رفعه بنجاح وعطاني رابط واستخدمته بدل من localhost:3000 وبعدين حطيت رابط مشروع في cors بهذه شكل app.use(cors({ origin: 'https://mern-image-gallery-app.netlify.app/', credentials: true })); ورفعت مجلد عميل على Netlify وخادم لم يعمل. اقتباس
0 محمد_عاطف نشر منذ 5 ساعة أرسل تقرير نشر منذ 5 ساعة يجب حذف الشرطة المائلة (/) من النهاية فالمتصفحات ترسل ال Origin بدون شرطة مائلة في النهاية والكود لديك يحتوي عليها. لذلك قم بإزالة / من نهاية الرابط: app.use(cors({ origin: 'https://mern-image-gallery-app.netlify.app', credentials: true })); وتأكد من أن الكود السابق في بداية الملف لديك أى قبل أى route موجود حتى يتم تنفيذه أولا . وأخيرا بعد إجراء أي تعديل على ملف الخادم، يجب أن تقوم بإعادة نشره (re-deploy) على Render حتى يتم تطبيق التغييرات وتأكد من أن عملية النشر تمت بنجاح على Render. اقتباس
0 Zen Eddin Allaham نشر منذ 4 ساعة الكاتب أرسل تقرير نشر منذ 4 ساعة مشكلة لم تنحل هكذا استخدمته في axios import express from 'express'; import dotenv from 'dotenv'; import { connectDB } from './libs/connectDB.js'; import userRouter from './routes/user.route.js'; import imageRouter from './routes/image.route.js'; import cors from 'cors'; import path from 'path'; dotenv.config(); const app = express(); app.use(express.json()) app.use(cors({ origin: 'https://mern-image-gallery-app.netlify.app', credentials: true })); connectDB(); const port = process.env.PORT || 3000; app.get('/' , (req , res) => { res.send("Hello World!"); }); app.use('/api/auth' ,userRouter); app.use('/api/images' ,imageRouter); app.use('/uploads', express.static(path.join(process.cwd(), 'public', 'uploads'))); app.listen(port , () => { console.log(`Server is running on port ${port}`) }); import { useState, useEffect } from 'react'; import axios from 'axios'; import { FaHeart, FaRegHeart } from 'react-icons/fa'; import { useNavigate } from 'react-router-dom'; import toast from 'react-hot-toast'; const Home = () => { const [images, setImages] = useState([]); const [loading, setLoading] = useState(true); const [message, setMessage] = useState(""); const [modalImage, setModalImage] = useState(null); const navigate = useNavigate(); const token = localStorage.getItem("token"); useEffect(() => { const fetchImages = async () => { try { const res = await axios.get("https://mern-stack-image-gallery-app.onrender.com/api/images"); setImages(res.data); } catch (err) { console.error(err); setMessage("حدث خطأ أثناء جلب الصور"); } finally { setLoading(false); } }; fetchImages(); }, []); const handleLike = async (id) => { if (!token) { toast.error("يجب تسجيل الدخول اولاُ", { duration: 3000 }); navigate("/login"); return; } try { const res = await axios.post( `https://mern-stack-image-gallery-app.onrender.com/api/images/like/${id}`, {}, { headers: { Authorization: `Bearer ${token}` } } ); setImages(images.map((img) => img._id === id ? { ...img, likes: res.data.likes } : img )); } catch (error) { console.error(error); toast.error(error.response?.data?.message || "حدث خطأ أثناء الإعجاب بالصورة"); } }; if (loading) return <p className="text-center mt-10">جارٍ تحميل الصور...</p>; if (message) return <p className="text-center mt-10 text-red-500">{message}</p>; return ( <div className="container mx-auto p-4 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4"> {images.map((img) => ( <div key={img._id} className="border rounded shadow p-2 bg-white relative h-72"> <img src={`https://mern-stack-image-gallery-app.onrender.com${img.imageUrl}`} alt={img.title || "img"} className="w-full h-48 object-cover rounded cursor-pointer" onClick={() => setModalImage(img)} /> <h3 className=" mt-2 font-semibold">{img.title}</h3> <p className='text-gray-800'>{img.description}</p> <button onClick={() => handleLike(img._id)} className="absolute top-2 right-2 text-red-500 text-xl" > {img.likes && img.likes > 0 ? <FaHeart /> : <FaRegHeart />} <span className="ml-1">{img.likes || 0}</span> </button> </div> ))} {modalImage && ( <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"> <div className="bg-white rounded p-4 max-w-lg w-full relative"> <button onClick={() => setModalImage(null)} className="absolute top-2 right-2 text-xl font-bold text-gray-600 hover:text-black" > ❌ </button> <img src={`https://mern-stack-image-gallery-app.onrender.com${modalImage.imageUrl}`} alt={modalImage.title} className="w-full h-auto rounded mb-4" /> <h2 className="text-xl font-bold mb-2">{modalImage.title}</h2> <p className="text-gray-700">{modalImage.description}</p> </div> </div> )} </div> ); }; export default Home; اقتباس
0 محمد_عاطف نشر منذ 4 ساعة أرسل تقرير نشر منذ 4 ساعة بتاريخ 16 دقائق مضت قال Zen Eddin Allaham: مشكلة لم تنحل هكذا استخدمته في axios import express from 'express'; import dotenv from 'dotenv'; import { connectDB } from './libs/connectDB.js'; import userRouter from './routes/user.route.js'; import imageRouter from './routes/image.route.js'; import cors from 'cors'; import path from 'path'; dotenv.config(); const app = express(); app.use(express.json()) app.use(cors({ origin: 'https://mern-image-gallery-app.netlify.app', credentials: true })); connectDB(); const port = process.env.PORT || 3000; app.get('/' , (req , res) => { res.send("Hello World!"); }); app.use('/api/auth' ,userRouter); app.use('/api/images' ,imageRouter); app.use('/uploads', express.static(path.join(process.cwd(), 'public', 'uploads'))); app.listen(port , () => { console.log(`Server is running on port ${port}`) }); import { useState, useEffect } from 'react'; import axios from 'axios'; import { FaHeart, FaRegHeart } from 'react-icons/fa'; import { useNavigate } from 'react-router-dom'; import toast from 'react-hot-toast'; const Home = () => { const [images, setImages] = useState([]); const [loading, setLoading] = useState(true); const [message, setMessage] = useState(""); const [modalImage, setModalImage] = useState(null); const navigate = useNavigate(); const token = localStorage.getItem("token"); useEffect(() => { const fetchImages = async () => { try { const res = await axios.get("https://mern-stack-image-gallery-app.onrender.com/api/images"); setImages(res.data); } catch (err) { console.error(err); setMessage("حدث خطأ أثناء جلب الصور"); } finally { setLoading(false); } }; fetchImages(); }, []); const handleLike = async (id) => { if (!token) { toast.error("يجب تسجيل الدخول اولاُ", { duration: 3000 }); navigate("/login"); return; } try { const res = await axios.post( `https://mern-stack-image-gallery-app.onrender.com/api/images/like/${id}`, {}, { headers: { Authorization: `Bearer ${token}` } } ); setImages(images.map((img) => img._id === id ? { ...img, likes: res.data.likes } : img )); } catch (error) { console.error(error); toast.error(error.response?.data?.message || "حدث خطأ أثناء الإعجاب بالصورة"); } }; if (loading) return <p className="text-center mt-10">جارٍ تحميل الصور...</p>; if (message) return <p className="text-center mt-10 text-red-500">{message}</p>; return ( <div className="container mx-auto p-4 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4"> {images.map((img) => ( <div key={img._id} className="border rounded shadow p-2 bg-white relative h-72"> <img src={`https://mern-stack-image-gallery-app.onrender.com${img.imageUrl}`} alt={img.title || "img"} className="w-full h-48 object-cover rounded cursor-pointer" onClick={() => setModalImage(img)} /> <h3 className=" mt-2 font-semibold">{img.title}</h3> <p className='text-gray-800'>{img.description}</p> <button onClick={() => handleLike(img._id)} className="absolute top-2 right-2 text-red-500 text-xl" > {img.likes && img.likes > 0 ? <FaHeart /> : <FaRegHeart />} <span className="ml-1">{img.likes || 0}</span> </button> </div> ))} {modalImage && ( <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"> <div className="bg-white rounded p-4 max-w-lg w-full relative"> <button onClick={() => setModalImage(null)} className="absolute top-2 right-2 text-xl font-bold text-gray-600 hover:text-black" > ❌ </button> <img src={`https://mern-stack-image-gallery-app.onrender.com${modalImage.imageUrl}`} alt={modalImage.title} className="w-full h-auto rounded mb-4" /> <h2 className="text-xl font-bold mb-2">{modalImage.title}</h2> <p className="text-gray-700">{modalImage.description}</p> </div> </div> )} </div> ); }; export default Home; هناك خطأ شائع يحدث عندما نستخدم credentials: true عندما تضبط الخادم (Express) ليقبل credentials: true فأنت تخبر المتصفح أنك تثق في هذا الموقع لدرجة أنك تسمح له بإرسال واستقبال الكوكيز أو التوكنز (headers) الخاصة بالمصادقة. وفي المقابل يجب على العميل (React/Axios) أن يرسل withCredentials: true مع كل طلب وبدون تلك الخطوة سيرفض المتصفح إرسال الطلب كإجراء أمني. لذلك أولا في الخادم يجب ترتيب الـ Middlewares قم بجعل ال cors هو أول middleware يتم استخدامه حتى قبل express.json() وهذا يضمن أن الطلبات يتم معالجتها بشكل صحيح. بعد ذلك في الواجهة الأمامية أضف withCredentials: true إلى جميع طلبات axios الخاصة بك : useEffect(() => { const fetchImages = async () => { try { const res = await axios.get( "https://mern-stack-image-gallery-app.onrender.com/api/images", { withCredentials: true } // أضف هذا ); setImages(res.data); } catch (err) { // ... } finally { // ... } }; fetchImages(); }, []); اقتباس
السؤال
Zen Eddin Allaham
عندي مشروع React + Express.js ورفعت مجلد خادم على render و تم رفعه بنجاح وعطاني رابط واستخدمته بدل من localhost:3000
وبعدين حطيت رابط مشروع في cors بهذه شكل
ورفعت مجلد عميل على Netlify وخادم لم يعمل.
3 أجوبة على هذا السؤال
Recommended Posts
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.