تعتمد node.js
على محرك Chrome
v8
لتشغيل كود js
، حتى نتمكن من التخلص من بيئة المتصفح وتشغيل كود js
مباشرة في وحدة التحكم، مثل hello world
التالي رمز hello world
console.log('hello World');
يمكنك تشغيله مباشرة باستخدام node
في وحدة التحكم
توفر الوحدة النمطية http
المضمنة في node.js
إمكانات خدمة http
الأساسية. بناءً على مواصفات CommonJS
، يمكننا استخدام وحدة http
require
الاستيراد. توجد وظيفة createServer
في ملف http
header
request
url
request
خادم http
يتلقى وظيفة رد الاتصال response
response
أساسي لإعادة المعلومات إلى العميل، حيث يقوم بتغليف بعض العمليات المتعلقة بنص الاستجابة، على سبيل المثال، تسمح لنا طريقة response.writeHead
بتخصيص معلومات الرأس ورمز الحالة لنصالإرجاع نص الاستجابة، نسميه طريقة response.end()
، يمكنك إرسال نص الاستجابة إلى العميل. باستخدام وظيفة createServer
يتم إنشاء كائن Server
لنا فقط، ولكنه لا يسمح لنا بالاستماع إليه يمكننا بالفعل listen
server
listen
كخادم، المعلمة الأولى هي رقم منفذ الاستماع، والمعلمة الثانية هي عنوان ip
للمضيف المنضم، والمعلمة الثالثة هي وظيفة رد اتصال.،
http
الحصول على الاستثناء الذي تم طرحه من المعلمة الأولى لوظيفة رد الاتصال. يمكننا اختيار معالجة الاستثناء لجعل خادمنا أكثر قوةباستخدام وحدة http
لإنشاء خادم بسيط.
const { createServer } = require('http' ); const HOST = 'localhost'; منفذ ثابت = '8080'؛ خادم const = createServer((req, resp) => { // المعلمة الأولى هي رمز الحالة الذي يُرجعه // والمعلمة الثانية هي معلومات رأس الاستجابة resp.writeHead(200, { 'نوع المحتوى': 'نص/عادي' }); console.log("الخادم يعمل..."); // طريقة إنهاء المكالمة لإخبار الخادم بأن الطلب قد تم استيفائه resp.end('مرحبًا خادم http nodejs'); }); server.listen(PORT, HOST, (خطأ) => { إذا (خطأ) { console.log('شيء خاطئ:'، خطأ)؛ يعود؛ } console.log(`الخادم يستمع إلى http://${HOST}:${PORT} ...`); });
يمكنك محاولة تشغيله مباشرة باستخدام node
وإنشاء خادم خاص بك! بعد تشغيل الخادم، يمكن للمتصفح الوصول إلى الخادم عن طريق الوصول إلى http://localhost:8080
يمكنك أيضًا استخدام nodemon
لتشغيله، بحيث عندما يتغير الكود الخاص بنا، لا نحتاج إلى إنهاء البرنامج يدويًا وإعادة تشغيل
npm
i -gNodemon
بدون استخدام npx nodemon
فهو أيضًا بسيط جدًا، فقط قم بتغيير أمر node
إلى أمر nodemon
Nodemon http-server.js
عندما استخدمنا كائنات createServer
و resp
سابقًا، لم نتمكن من رؤية أي مطالبات بناء جملة. يجب علينا اتباع وثائق node
الرسمية للتحقق من ذلك في أي وقت يمكن استخدام .d.ts
في توفير وظيفة موجه بناء الجملة. لاحظ أننا لا نستخدم ts
للتطوير، ولكننا نستخدم فقط وظيفة موجه بناء الجملة
npm init -y
@types/node
- pnpm i @types/node -D
jsconfig.json
في دليل المشروع، واستبعاد node_modules
، ليست هناك حاجة للتحقق منه{ "compilerOptions": { "checkJs": صحيح }, "استبعاد": ["node_modules", "**/node_modules/*"] }
أتساءل عما إذا كنت قد اكتشفت أن هناك بالفعل خطأ في الكود أعلاه؟ يمكن أن يساعدنا checkJs
في التحقق من أخطاء النوع، ويمكنك اختيار ما إذا كنت تريد تشغيله وفقًا لاحتياجاتك، أم لا، وسيطالبنا على الفور بعدم تطابق نوع المعلمة.
في هذا الوقت، قم بتمرير الماوس فوق طريقة listen
ويمكنك رؤية توقيع الطريقة.
كما ترون، يجب أن تكون معلمة port
الأصلية من النوع number
، ولكن عندما حددناها، كانت من النوع string
، لذا فهي غير متطابقة. فقط قم بتغييرها إلى 8080
من number
ويمكنك عرض وثائق واجهة api
ذات الصلة مباشرة دون فتح node
الرسمية، استغرق الأمر وقتًا طويلاً للعثور على المستند والتحقق منه.
. قام http server
البسيط الخاص بنا بإرجاع جملة واحدة فقط، فهل من الممكن إرجاع جمل متعددة؟ يتطلب ذلك استخدام طريقة write
للكائن resp
، end
يمكن إرجاع المحتوى إلا مرة واحدة. وبدلاً من ذلك، يمكننا كتابة end
في نص write
عدة مرات تمرير أي معلمات فقط دعه يكمل وظيفة إرسال نص الاستجابة
const { createServer } = require("http"); const HOST = "المضيف المحلي"; منفذ ثابت = 8080؛ خادم const = createServer((req, resp) => { resp.writeHead(200, { "نوع المحتوى": "نص/عادي" }); console.log("الخادم يعمل..."); // اكتب بعض الجمل لوريم resp.write("Lorem ipsum dolor sit amet consectetur adipisicing elit.n"); resp.write("هل هناك أي معلومات مختارة؟n"); resp.write("Aut, quam quo!n"); resp.end(); }); server.listen(PORT, HOST, (خطأ) => { إذا (خطأ) { console.log("شيء خاطئ:"، خطأ)؛ يعود؛ } console.log(`الخادم يستمع إلى http://${HOST}:${PORT} ...`); });
هذه المرة كتبنا ثلاث جمل، وأصبح التأثير الآن هكذا
لا يمكننا فقط إرجاع سلسلة إلى المتصفح، ولكن أيضًا قراءة محتوى ملف html
مباشرة وإعادته إلى المتصفح نتيجة لذلك، وهذا يتطلب استخدام وحدة Node.js
مدمجة أخرى -. fs
، والتي توفر الوحدة وظيفة تشغيل الملف. يمكنك استخدام fs.readFile
لقراءة الملفات بشكل غير متزامن، ولكنها لن تُرجع كائنًا promise
، لذلك نحتاج إلى تمرير رد اتصال للتعامل مع العملية بعد قراءة الملف يمكن أيضًا استخدام fs.readFileSync
لحظر قراءة الملفات بشكل متزامن، وهنا نختار القراءة غير المتزامنة
const { createServer } = require("http"); const fs = require("fs"); const HOST = "المضيف المحلي"; const PORT = 8080;const server = createServer((req, resp) => { // قم بتغيير نوع MIME من نص/عادي إلى نص/html resp.writeHead(200, { "نوع المحتوى": "text/html" }); // اقرأ محتوى ملف HTML fs.readFile("index.html"، (خطأ، بيانات) => { إذا (يخطئ) { وحدة التحكم.خطأ( "حدث خطأ أثناء قراءة محتوى ملف html: "، يخطئ ); } console.log("نجاح العملية!"); resp.write(data); resp.end(); }); }); server.listen(PORT, HOST, (خطأ) => { إذا (خطأ) { console.log("شيء خاطئ:"، خطأ)؛ يعود؛ } console.log(`الخادم يستمع إلى http://${HOST}:${PORT} ...`); });
النتيجة الحالية هي كما يلي:
تم إرجاع html
ملاحظة: هنا تحتاج إلى تغيير **Content-Type**
لرأس الاستجابة إلى **text/html**
لإعلام المتصفح بأننا نعيد محتوى الملف **html**
. إذا كنت لا تزال تستخدم **text/plain**
، فلن يقوم المتصفح بتحليل المحتوى الذي تم إرجاعه، حتى لو كان يتوافق مع بناء جملة **html**
، فلن يتم تحليله، تمامًا كما يلي:
عندما نحتاج إلى كتابة خادم خلفي مسؤول فقط عن إرجاع بيانات الواجهة، نحتاج إلى إرجاع المحتوى بتنسيق json
، وأعتقد أنك ذكي وتعرف كيفية التعامل معه:
MIME
على application/json
resp.write
، يتم تمرير سلسلة json
. يمكنك استخدام JSON.stringify
لمعالجة الكائن وإرجاعconst { createServer } = require("http"); const HOST = "المضيف المحلي"; منفذ ثابت = 8080؛ خادم const = createServer((req, resp) => { // قم بتغيير نوع MIME إلى application/json resp.writeHead(200, { "نوع المحتوى": "application/json" }); // إنشاء بيانات json باستخدام كائن const jsonDataObj = { الكود: 0، الرسالة: "النجاح"، بيانات: { الاسم: "البلاستيسين"، العمر: 20, الهواية: "البرمجة"، }, }; resp.write(JSON.stringify(jsonDataObj)); resp.end(); }); server.listen(PORT, HOST, (خطأ) => { إذا (خطأ) { console.log("شيء خاطئ:"، خطأ)؛ يعود؛ } console.log(`الخادم يستمع إلى http://${HOST}:${PORT} ...`); });
وكانت النتائج كما يلي:
فكرة إرجاع ملفات pdf مشابهة لفكرة إرجاع ملفات html
من قبل، فكلاهما عبارة عن عملية تعيين نوع MIME
لرأس الاستجابة، وقراءة الملف، وإرجاع محتوى الملف شيء مختلف، فكرتنا هي القيام بذلك أثناء تشغيل الخادم. لإنشاء ملف pdf
وإعادته، تحتاج إلى تغيير نوع MIME
إلى application/pdf
لإنشاء ملف pdf
، تحتاج إلى استخدام مكتبة - pdfkit
pnpm i pdfkit
أولاً، نكتب دالة لإنشاء ملف pdf
، لأن إنشاء ملف pdf
يتطلب أيضًا إجراء بعض عمليات الكتابة، لست متأكدًا من موعد اكتمالها، ولكن يجب أن ينتظر طلبنا حتى يتم إنشاء ملف pdf
قبل أن نتمكن من ذلك. الحصول على رد، لذلك نحن بحاجة إلى جعله غير متزامن وإرجاع promise
/** * @description إنشاء ملف pdf */const createPdf = () => { إرجاع وعد جديد ((حل، رفض) => { إذا (!fs.existsSync("example.pdf")) { // إنشاء كائن PDFDocument const doc = new PDFDocument(); // إنشاء دفق الكتابة عن طريق توصيل محتوى PDF. doc.pipe(fs.createWriteStream("example.pdf")); // أضف بعض المحتويات إلى مستند pdf doc.fontSize(16).text("Hello PDF", 100, 100); // أكمل عملية إنشاء ملف PDF. doc.end(); } حل("النجاح"); }); };
يتم استخدام عملية خط الأنابيب هنا لنقل محتويات كائن PDFDocument
إلى دفق الكتابة المنشأ حديثًا من خلال خط الأنابيب. عند اكتمال العملية، نقوم بإعلام العالم الخارجي من خلال resovle
إنشاء ملف pdf
ثم استدعاء
const. الخادم في رمز الخادم = createServer(async (req, resp) => { // قم بتغيير نوع MIME إلى application/pdf resp.writeHead(200, { "نوع المحتوى": "application/pdf" }); // إنشاء ملف pdf في انتظار createPdf(); // قراءة ملف pdf الذي تم إنشاؤه fs.readFile("example.pdf", (err, data) => { إذا (يخطئ) { وحدة التحكم.خطأ( "حدث خطأ أثناء قراءة محتوى ملف pdf: "، يخطئ ); رمي خطأ. } console.log("نجاح العملية!"); resp.end(data); }); }); server.listen(PORT, HOST, (خطأ) => { إذا (خطأ) { console.log("شيء خاطئ:"، خطأ)؛ يعود؛ } console.log(`الخادم يستمع إلى http://${HOST}:${PORT} ...`); });
الآن يمكن للمتصفح قراءة ملف pdf
الذي تم إنشاؤه
كما هي. اقرأ ملفًا صوتيًا، ثم أرسله إلى كائن resp
عبر خط أنابيب وأعده
const { createServer } = require("http"); const { stat, createReadStream } = require("fs"); const HOST = "المضيف المحلي"; منفذ ثابت = 8080؛ خادم const = createServer((req, resp) => { // قم بتغيير نوع MIME إلى audio/mpe resp.writeHead(200, { "نوع المحتوى": "audio/mp3" }); const mp3FileName = "audio.mp3"; stat(mp3FileName, (err, stats) => { إذا (stats.isFile()) { const rs = createReadStream(mp3FileName); // قم بتوجيه دفق القراءة إلى resp rs.pipe(resp); } آخر { resp.end("ملف mp3 غير موجود"); } }); }); server.listen(PORT, HOST, (خطأ) => { إذا (خطأ) { console.log("شيء خاطئ:"، خطأ)؛ يعود؛ } console.log(`الخادم يستمع إلى http://${HOST}:${PORT} ...`); });
التأثير كالتالي
بعد الفتح، توجد واجهة لتشغيل الصوت، وهي عرض الملفات الصوتية التي يوفرها chrome
. عند فتح وحدة التحكم، ستجد أن هناك ملفات صوتية تم إرجاعها.
ملاحظة: بعد تمرير دفق الملف الصوتي إلى **resp**
عبر الأنبوب ، ليست هناك حاجة لاستدعاء الأسلوب **resp.end()**
، لأن هذا سيؤدي إلى إغلاق الاستجابة بالكامل ويتسبب في إغلاق الملف الصوتي. غير متاح.
معالجة ملفات الفيديو والملفات الصوتية هي نفسها، باستثناء أن نوع MIME
يحتاج إلى التغيير إلى video/mp4
. كل شيء آخر هو نفسه
const { createServer } = require("http"); const { stat, createReadStream } = require("fs"); const HOST = "المضيف المحلي"; منفذ ثابت = 8080؛ خادم const = createServer((req, resp) => { // قم بتغيير نوع MIME إلى audio/mpe resp.writeHead(200, { "نوع المحتوى": "audio/mp4" }); const mp4FileName = "video.mp4"; stat(mp4FileName, (err, stats) => { إذا (stats.isFile()) { const rs = createReadStream(mp4FileName); // قم بتوجيه دفق القراءة إلى resp rs.pipe(resp); } آخر { resp.end("ملف mp4 غير موجود"); } }); }); server.listen(PORT, HOST, (خطأ) => { إذا (خطأ) { console.log("شيء خاطئ:"، خطأ)؛ يعود؛ } console.log(`الخادم يستمع إلى http://${HOST}:${PORT} ...`); });
تعلمنا:
Node
لإنشاء خادم http
JSON
js
pdf
html
على الرغم من أن المحتوى بسيط، إلا أنني آمل أن تتمكن من متابعته وتجربته لا يعني أنك تعرف ذلك، ولن تجد مشاكلك الخاصة إلا بعد تنفيذه فعليًا.