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

مشكلة في عمل طلب بإستخدام axios داخل مكون React؟

Adam Ebrahim

السؤال

لدي خادم Backend يعمل بـ Flask ، ولدي restful routes  لطباعة البيانات المرسلة من قبل المستخدم بالشكل التالي:

print (request.form['username'])
print (request.form['email'])

 وعندما أقوم بتنفيذ الأمر التالي:

curl http://localhost:8080/api/data -X PUT -d username=adam -d email=adam@gmail.com

يعمل كل شيء بشكل سليم عند تنفيذ الأمر السابق وأحصل على البيانات التي أريد (username - email)، لكن المشكلة هي عندما أستخدم axios لإرسال طلب إلى الخادم فلا يتم إرسال البيانات بالشكل الصحيح، حاولت فحص كود cURL من DevTools ووجود أنه بالشكل التالي:

curl 'http://localhost:8080/api/data' -X PUT -H 'Pragma: no-cache' -H 'Origin: http://localhost:8080' -H 'Accept-Encoding: gzip, deflate, sdch' -H 'Accept-Language: en-US,en;q=0.8' -H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36 Edg/89.0.774.77' -H 'Content-Type: application/json;charset=UTF-8' -H 'Accept: application/json, text/plain, */*' -H 'Cache-Control: no-cache' -H 'Referer: http://localhost:8080/settings' -H 'Connection: keep-alive' --data-binary '{"username":"adam","email":"adam@gmail.com"}' --compressed

لا أعرف لماذ يقوم المتصفح بإضافة الكثير من الـ headers في الطلب، لكن أعتقد أن المشكلة هي في نوع الطلب Content-Type، كيف أقوم بتحديده في Axios عندما أستعمله بالشكل التالي:

const handleSubmit = async (e) => {
        e.preventDefault();
        const user = {username: 'adam', email: 'adam@gmail.com'};
        await axios.post('http://localhost:8080/api/v1/data', user);        
    };

 

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

Recommended Posts

  • 1

المشكلة تكمن في أن السيرفر يتوقع من request body أن يكون من نوع application/x-www-form-urlencoded فكيف نرسل بيانات من هذا النوع من خلال axios؟ ببساطة بتحويل الكود التالي:

const handleSubmit = async (e) => {
  e.preventDefault();
  const user = {username: 'adam', email: 'adam@gmail.com'};
  await axios.post('http://localhost:8080/api/v1/data', user);        
};

إلى التالي:

const handleSubmit = async (e) => {
  e.preventDefault();
  const user = {username: 'adam', email: 'adam@gmail.com'};
  await axios.post('http://localhost:8080/api/v1/data', new URLSearchParams(user));        
};

عند تمرير object من نمط URLSearchParams إلى axios تفهم axios أنك تريد إرسال فورم وتضع Content-Type بشكل تلقائي على x-www-form-urlencoded.

هذا ينفع طالما ليس هنالك file uploads أما إن كان هناك ملفات تريد رفعها إلى جانب الحقول النصية فعليك استخدام FormData هكذا:

const handleSubmit = async (e) => {
  e.preventDefault();
  const user = {username: 'adam', email: 'adam@gmail.com'};
  const userData = new FormData();
  userData.set("username",user.username);
  userData.set("email",user.email);
  userData.set("somefile",somefileInputRef.file);
  await axios.post('http://localhost:8080/api/v1/data', userData);        
};

عند تمرير FormData إلى axios يتم تمرير Content-Type إلى multipart/form-data ولكن انتبه من أن على السيرفر توقع ذلك والتعامل مع الملفات المرفوعة بطريقة ما.

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

  • 0

في حالة كنت تريد تعديل الcontent-type الخاص بالheader للaxios

يمكنك ذلك عن طريق الparameter الثالث الخاص بالaxios (الparameter الثالث هو الoptions للaxios)

مثال الكود التالي:

    axios.post('url', data, {
        headers: {
            'Content-Type': 'application/json',
        }
    }
    )

 

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

  • 0

المدخل (parameter) الثاني ل axios.get والثالث ل axios.post و axios.put هو الخيارات الإضافية وهو عبارة عن object ومن إخلاله يمكنك إضافة ال content-type و غيره من الخيارات كما في الكود الموضح في الأسفل

const handleSubmit = async (e) => {
        e.preventDefault();
        const user = {username: 'adam', email: 'adam@gmail.com'};
        await axios.post('http://localhost:8080/api/v1/data', user, {
	headers: { 'content-type': 'application/x-www-form-urlencoded' }
});        
    };

 

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

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

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

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

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   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.

  • إعلانات

  • تابعنا على



×
×
  • أضف...