اذهب إلى المحتوى
  • 0

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

Ahmed Sawy

السؤال

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

بالتاكيد استطيع رفع الصور وعمل 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
اضافة صورة بوست مان
رابط هذا التعليق
شارك على الشبكات الإجتماعية

Recommended Posts

  • 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',
        

  }
})
 }

 

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

  • 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
بتاريخ 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
رابط هذا التعليق
شارك على الشبكات الإجتماعية

  • 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
بتاريخ 5 دقائق مضت قال Nuhla Almasri:

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

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

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

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...