واجهت مثل هذا الشرط في عملي ، وكنت بحاجة إلى استخدام NodeJS لتحميل الملفات. اعتدت أن أعرف فقط كيفية تحميل الملفات من خلال المتصفح. إذا استخدمت Nodejs ، فهذا يعادل محاكاة سلوك المتصفح. بعد Google ، أدركت أن المتصفح يستخدم ببساطة بروتوكول HTTP لنقل البيانات إلى الخادم. البروتوكول المحدد هو "RFC 1867 - تحميل الملف القائم على النماذج في HTML". تحميل الملفات من خلال نماذج النماذج على المتصفح من خلال هذا البروتوكول. يمكننا أولاً معرفة البيانات التي يرسلها المستعرض إلى الخادم ، ثم يمكننا تنفيذ وظيفة التحميل وفقًا للنسخة. عندما يتعلق الأمر بتحميل الملفات على نماذج النماذج ، يجب أن يكون الجميع على دراية بـ:
<form action = "http://www.qq.com/" method = "post"> <input type = "text" name = "text1" /> <br /> <input type = "text" name =
عند الإرسال ، يمكنك أن ترى أنه يتم إرسال البيانات التالية إلى الخادم باستخدام Fiddler لالتقاط الحزمة:
بعد http://www.qq.com/ http/1.1
المضيف: www.qq.com
طول المحتوى: 23
نوع المحتوى: التطبيق/X-WWW-Form-urlencoded ؛ charset = UTF-8
text1 = hello & text2 = World
تجدر الإشارة إلى أن الإعدادات الافتراضية من نوع المحتوى للتطبيق/X-WWW-Form-urlencoded ، وبالتالي سيتم ترميز الرسالة عن URL. على سبيل المثال ، سيتم ترميز "Hello" على أنها ٪ E4 ٪ BD ٪ A0 ٪ E5 ٪ A5 ٪ BD.
بعد ذلك ، دعونا نلقي نظرة على كيفية تحميل النموذج. يجب أن يكون الجميع على دراية:
<form action = "http://www.qq.com" method = "post" enctype = "multipart/form-data"> <input type = "file" name = "myfile"/> <input type = "president" value = "submit"/> </form>
ثم قم بإنشاء ملف نصي Topload.txt جديد مع كلمة Hello World فقط وقم بتحميلها. نستخدم Fiddler للاستيلاء على الحزمة. يمكننا أن نجد أن إرسال البيانات السابقة أكثر تعقيدًا قليلاً (تمت إزالة الكثير من خطوط الطلب غير المرتبطة ، مثل التحكم في ذاكرة التخزين المؤقت وملفات تعريف الارتباط):
بعد http://www.qq.com/ http/1.1
المضيف: www.qq.com
طول المحتوى: 199
نوع المحتوى: multipart/form-data ؛ الحدود = --- webkitformboundarywr3x7sxbyq4zf5g
----- webkitformboundarywr3x7sxbyq4zf5g
إقرار المحتوى: data form ؛ name = "myfile" ؛ Filename = "TOPLOAD.TXT"
نوع المحتوى: النص/عادي
مرحبا بالعالم
----- webkitformboundarywr3x7sxbyq4zf5g-
وفقًا لتعريف RFC 1867 ، نحتاج إلى إنشاء جزء من بيانات الحدود. لا يمكن أن تظهر هذه البيانات في مكان آخر في المحتوى. يمكن تعريف هذا بنفسك. قد تكون خوارزمية توليد كل متصفح مختلفة. الحدود أعلاه هي فصل البيانات. بعد إنشاء البيانات المنفصلة ، يمكن وضع البيانات المنفصلة في نوع المحتوى في الرأس ونقلها إلى الخادم ، أي نوع المحتوى أعلاه: multipart/form-data ؛ الحدود = --- webkitformboundarywr3x7sxbyq4zf5g ، بالإضافة إلى ذلك ، يجب فصل المحتوى الذي تم تحميله إلى عدة قطاعات مع بيانات منفصلة ، وكل جزء من البيانات له اسم الملف ، والاسم عند التحميل. يستخدم الخادم هذا الاسم لتلقي الملف ، ونوع محتوى نوع الملف. في هذا المثال ، النص/عادي. إذا كانت صورة PNG التي تم تحميلها هي Image/PNG ، فهي صورة/PNG. بعد سطر فارغ من نوع الملف ، يسهل فهم محتوى الملف الذي تم تحميله. في هذا المثال ، يكون الملف النصي الذي تم تحميله بحيث يمكن عرض المحتوى مباشرة. إذا كان ملف الصورة الذي تم تحميله عبارة عن ملف ثنائي ، فسيقوم Fiddler بعرض التعليمات البرمجية المشوهة. بعد انتهاء محتوى الملف ، هناك خط فارغ بالإضافة إلى بيانات الحدود.
بعد فهم تفاصيل تنسيق الإرسال ، فإن الخطوة التالية هي استخدام NodeJs لبرمجة وتنفيذها. ببساطة ، فقط أرسل البيانات إلى الخادم وفقًا للتنسيق.
const http = require ('http') ؛ const fs = require ('fs') ؛ // عنوان المنشور هو php في الخدمة المحلية ، المستخدمة لاختبار ما إذا كان التحميل ناجحًا var ortions = {hostname: 'localhost' '--- webkitformboundaryjlvkbqxtii0ygpab' ؛ // اقرأ محتوى الملف الذي يحتاج إلى تحميل fs.readfile (. "نوع المحتوى: نص/عادي/r/n/r/n '؛ payload + = data ؛ payload + ='/n-- ' + boundarykey +'-'؛ chunk) ؛}) ؛}) ؛ req.on ('error' ، function (e) {console.error ("error:"+e) ؛}) ؛ // اكتب الحدود ، وحجم البيانات المراد إرسالها ، والبيانات نفسها في requer req.setheader ('type-type' ، 'multipart/form-data ؛ الحدود = '+boundarykey+' '') ؛ req.setheader ('طول المحتوى' ، buffer.bytelength (payload ، 'utf8')) ؛ req.write (payload) ؛ req.end () ؛}) ؛ينصب تركيز هذه المقالة على فهم البروتوكول وتنفيذه باستخدام الكود. لا يزال هناك العديد من التحسينات في تنظيم الكود.
أخيرًا ، في Apache المحلي ، ببساطة كتابة PHP لحفظ الملف الذي تم تحميله لاستخدامه كاختبار:
<؟ php $ filepath = './upload.txt' ؛move_uploaded_file($_files budap'myfile' pudap'tmp_name '] ، $ filepath) ؛ echo "ok" ؛؟>؟>؟
بالإضافة إلى ذلك ، وفقًا لـ RFC 1867 ، يمكن تحقيق وظيفة تحميل ملفات متعددة مرة واحدة. لن يتم وصف هذا بالتفصيل هنا. إذا لزم الأمر ، راجع RFC 1867 للتنفيذ التفصيلي.
ما سبق هو تحميل ملف Node.js الذي تم تقديمه بواسطة المحرر. آمل أن يكون ذلك مفيدًا للجميع. إذا كان لديك أي أسئلة ، فيرجى ترك رسالة لي وسوف يرد المحرر على الجميع في الوقت المناسب. شكرا جزيلا لدعمكم لموقع wulin.com!