• 0

كيف أرفع صورة على السيرفر باستخدام Axios.

السلام عليكم .. 

بالتاكيد استطيع رفع الصور وعمل post request لكن هذه المرة نوع الملف مختلف حاولت على قدر الامكان ان اختصر الكود والشرح لكى لا اهدر وقتكم .. 

 

اولا .. كل شئ يعمل على مايرام بفضل الله .. حيث 

فى الفرونت اند .. 

image picker يعمل وتم تجربته بنجاح.

 

فى الباك اند

post api يعمل ايضا وتم تجربته بواسطة بوست مان عن طريق رفع ملفات form data ويعطينى 200 status code بفضل الله كما موضح بالصورة فى الاسفل 

 

لكن تااتى المشكله هنا وهى عندما اعمل بوست للصورة ولكن بواسطة رياكت ناتيف أندرويد اميلاتور حيث يظهر هذا الخطأ 

فى الترمنال الخاص بالباك اند  ...   Error: Multipart: Boundary not found

 

هذا هو الكود المختصر.. رياكت ناتيف 

import axios from 'axios';
import React, {useState} from 'react';
import {Button, View, Image} from 'react-native';
import ImagePicker from 'react-native-image-crop-picker';

function ImageScreen() {
  // هنا أقوم بتخزين اسم الصورة وهو عبارة عن امتداد الملف قبل ان ارسله الى الباك اند
  const [image, setImage] = useState('');

  //   الخطأ هنا
  const postData = () => {
    axios.post(
      'http://10.0.2.2:3000/posts',
      {
        name: 'new post', // هنا اختصرت الكود حفظا للوقت
        image: image,
      },
      {
        headers: {
          'Content-Type': `multipart/form-data`,
        },
      },
    );
  };

  //   لا داعى للنظر هنا فهو يعمل بشكل صحيح
  const choosePhotoFromLibrary = () => {
    ImagePicker.openPicker({
      width: 300,
      height: 300,
      cropping: true,
      compressImageQuality: 0.7,
    }).then(image => {
      console.log(image);
      setImage(image.path);
      this.bs.current.snapTo(1);
    });
    console.log(image);
  };

  return (
    <View>
      <Image style={{height: 300, width: 300}} source={{uri: image}} />
      <Button title="from device" onPress={choosePhotoFromLibrary} />
      <Button title="Post Data" onPress={postData} />
    </View>
  );
}

export default ImageScreen;

 

هذا هو كود النود .. ولكنى اعتقد ان المشكلة فى رياكت ناتيف لاننى ببساطة اختبرت هذا الاى بى اى بواسطة بوست مان ونجح الحمد لله  كما موضح فى الصورة فى الاسفل 

const express = require("express");
const router = express.Router();
const { postModel } = require("../model/post");
const multer = require("multer");

const FILE_TYPE_MAP = {
  "image/png": "png",
  "image/jpeg": "jpeg",
  "image/jpg": "jpg",
};

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    const isValid = FILE_TYPE_MAP[file.mimetype];
    let uploadError = new Error("invalid tpye");
    if (isValid) {
      uploadError = null;
    }
    cb(uploadError, "public/uploads");
  },
  filename: function (req, file, cb) {
    const fileName = file.originalname.split(" ").join("-");
    const extension = FILE_TYPE_MAP[file.mimetype];
    cb(null, `${fileName}-${Date.now()}.${extension}`); // cb >>> callback
  },
});

const uploadOptions = multer({ storage: storage });

router.post("/", uploadOptions.single("image"), async (req, res) => {
  const fileName = req.file.filename;
  const basePath = `${req.protocol}://${req.get("host")}/public/uploads/`;

  let newPost = postModel({
    name: req.body.name,
    image: `${basePath}${fileName}`,
  });
  newPost = await newPost.save();
  res.send(newPost);
});

module.exports = router;

 

 

60b4d059d2809_.thumb.png.8f4e38fea9591734bf163b4576aa4205.png

تمّ تعديل بواسطة Ahmed Sawy
اضافة صورة بوست مان

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 0

حسنا هنا دالة تقوم بخلق الformdata بشكل صحيح و إرجاع المعلومات الى طلب الaxios 

// دالة لخلق الformdata
// نرسل لها قيمة الصورة - و قيمة باقي المعلومات في المحتوي body
const createFormData = (photo, body = {}) => {
  // هنا نخلق ال Formdata
  const data = new FormData();
// نقوم بوضع المعلومات الخاصة بالصورة فيها 
  data.append('photo', {
    name: photo.fileName,
    type: photo.type,
    uri: Platform.OS === 'ios' ? photo.uri.replace('file://', '') : photo.uri,
  });

  // هنا نقوم بوضع جميع المحتويات داخل المحتوي Body
  Object.keys(body).forEach((key) => {
    data.append(key, body[key]);
  });

  // و نعيد البيانات من هنا 
  return data;
};

و هنا نقوم بأرسال جميع القيم بال axios 

 const postData  = () => {
    fetch(`${SERVER_URL}/api/upload`, {
      method: 'POST',
      // هنا نستخدم الدالة و نقوم بإعطائها المعلومات المرادة 
      body: createFormData(photo, { userId: '123' }),
    })
      .then((response) => response.json())
      .then((response) => {
        console.log('response', response);
      })
      .catch((error) => {
        console.log('error', error);
      });
  };

بالطبع يمكنك إستبدال الfetch ب ال axios

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 1

انت ترسل نوع multipart لذلك عليك حفظ قيمة الصورة بفورم داتا FormData أنا لا أرى أي مكان تقوم فيه بأنشاء أوبجكت من نوع FormData 

 

 const postData = () => {
   //  أضف هذه هنا مثلا 
   let formdata = new FormData();
   formdata.append("image", {uri: image.uri})



axios({
  url: 'http://10.0.2.2:3000/posts',
  method: 'POST',
  data: formdata,
  headers: {
   
           'Content-Type' : 'multipart/form-data',
        

  }
})
 }

 

1 شخص أعجب بهذا

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 0
بتاريخ منذ ساعة مضت قال Nuhla Almasri:

انت ترسل نوع multipart لذلك عليك حفظ قيمة الصورة بفورم داتا FormData أنا لا أرى أي مكان تقوم فيه بأنشاء أوبجكت من نوع FormData 

 


 const postData = () => {
   //  أضف هذه هنا مثلا 
   let formdata = new FormData();
   formdata.append("image", {uri: image.uri})



axios({
  url: 'http://10.0.2.2:3000/posts',
  method: 'POST',
  data: formdata,
  headers: {
   
           'Content-Type' : 'multipart/form-data',
        

  }
})
 }

 

للأسف حاولت بهذا الكود لكن ظهر لى هذا الايرور .. مع اننى ليس عندى اى مشاكل فى الانترنت 

WARN  Possible Unhandled Promise Rejection (id: 27):
Error: Network Error
createError@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.learny&modulesOnly=false&runModule=true:108031:26
handleError@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.learny&modulesOnly=false&runModule=true:107819:69
dispatchEvent@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.learny&modulesOnly=false&runModule=true:30817:31
setReadyState@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.learny&modulesOnly=false&runModule=true:29963:33

 

error.thumb.png.60a100063ee9420e3a7b60d02725b97a.png

 

تمّ تعديل بواسطة Ahmed Sawy

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 0

طبعا ستحتاج then و catch بغض النظر عن الطريقة المكتوبة بها الطلب لل  Axios لكن ما عليك فعله هو إرسال الصورة بخلق formdata 

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 0
بتاريخ 6 دقائق مضت قال Nuhla Almasri:

طبعا ستحتاج then و catch بغض النظر عن الطريقة المكتوبة بها الطلب لل  Axios لكن ما عليك فعله هو إرسال الصورة بخلق formdata 

انا فعلت هذا .. هل هذا صحيح ؟

عندما اقوم بعمل البوست فانه يظهر لى خطأ 

  const postData = () => {
    //  أضف هذه هنا مثلا
    let formdata = new FormData();
    formdata.append('image', {uri: image});

    axios({
      url: 'http://10.0.2.2:3000/posts',
      method: 'POST',
      data: formdata,
      headers: {
        'Content-Type': 'multipart/form-data',
      },
    })
      .then(res => console.log(res.data))
      .catch(error => {
        console.log(error);
      });
  };

 

تمّ تعديل بواسطة Ahmed Sawy
1 شخص أعجب بهذا

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 0

حسنا ستحتاج لمعرفة الآن ما الخطأ الذي سيطبعه من الطلب 

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 0
بتاريخ الآن قال Nuhla Almasri:

حسنا ستحتاج لمعرفة الآن ما الخطأ الذي سيطبعه من الطلب 

هذا هو 

 

WARN  Possible Unhandled Promise Rejection (id: 27):
Error: Network Error
createError@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.learny&modulesOnly=false&runModule=true:108031:26
handleError@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.learny&modulesOnly=false&runModule=true:107819:69
dispatchEvent@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.learny&modulesOnly=false&runModule=true:30817:31
setReadyState@http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false&app=com.learny&modulesOnly=false&runModule=true:29963:33

 

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 0

هل قمت بأرسال باقي المعلومات كال id و الأسم و جميع هذه الأمور التي تحتاجها لحفظ الملف من جهة السيرفر ؟

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 0
بتاريخ 5 دقائق مضت قال Nuhla Almasri:

هل قمت بأرسال باقي المعلومات كال id و الأسم و جميع هذه الأمور التي تحتاجها لحفظ الملف من جهة السيرفر ؟

انى فقط احتاج الى ارسال ال name ولكنى لا اعرف اين اكتبه 

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية

يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن