الوحدة HTTP في Node.js

من موسوعة حسوب
< Node.js
مراجعة 11:17، 23 أكتوبر 2018 بواسطة عبد اللطيف ايمش (نقاش | مساهمات) (استبدال النص - '\[\[تصنيف:(.*)\]\]' ب'{{SUBPAGENAME}}')
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)
اذهب إلى التنقل اذهب إلى البحث

مؤشر الاستقرار: 2 - مستقر

لاستخدام خادم وعميل HTTP يجب استدعاء require('http')‎.

صُمِمت واجهات HTTP في Node.js لدعم العديد من ميزات البروتوكول التي كانت صعبة الاستخدام تقليديًا. على وجه الخصوص، الرسائل الكبيرة، التي قد تكون مرمّزة كقطع ضخمة. وتكون الواجهة حريصة على عدم تخزين الطلبات أو الاستجابات بأكملها مؤقتًا، بحيث يكون المستخدم قادرًا على دفق البيانات (stream data).

تُمثَّل ترويسات رسائل HTTP بواسطة كائن مثل التالي:

{ 'content-length': '123',
  'content-type': 'text/plain',
  'connection': 'keep-alive',
  'host': 'mysite.com',
  'accept': '*/*' }

تُكتب المفاتيح بحروف صغيرة. ولا تُعدَّل القيم.

من أجل دعم الطيف الكامل لتطبيقات HTTP الممكنة، تُعد واجهة تطبيقات HTTP الخاصة ببيئة Node.js منخفضة المستوى. فهي تتعامل مع معالجة التدفق وتحليل الرسائل فقط. وتوزع رسالة في الترويسات والمتن ولكنها لا تحلل الترويسات والمتن الفعليين.

راجع message.headers للحصول على تفاصيل حول كيفية معالجة الترويسات المتكررة.

تُحفظ الترويسات الأولية عند استلامها في خاصية rawHeaders، وهي عبارة عن مصفوفة على الشكل [key, value, key2, value2,...]. على سبيل المثال، قد يحتوي كائن ترويسة الرسالة السابق على rawHeaders على الشكل التالي:

[ 'ConTent-Length', '123456',
  'content-LENGTH', '123',
  'content-type', 'text/plain',
  'CONNECTION', 'keep-alive',
  'Host', 'mysite.com',
  'accepT', '*/*' ]

الصنف http.Agent

أُضيف مع الإصدار: v0.3.4.

يكون الوكيل Agent مسؤولاً عن إدارة استمرارية الاتصال وإعادة استخدامه لعملاء HTTP. وهو يحافظ على قائمة انتظار الطلبات المعلقة لمضيف ومنفذ معين، مُعيدًا استخدام توصيل مقبس واحد لكل منها حتى تصبح قائمة الانتظار فارغة، وعند ذلك، إما يُدمَّر المقبس (socket) أو يوضع في مُجمِّع حيث سيُحتفظ به لاستخدامه مرة أخرى لطلبات نفس المضيف والمنفذ. يعتمد تدمير المقبس أو تخزينه على الخيار keepAlive.

تكون خاصية TCP Keep-Alive مفعلة بالنسبة للاتصالات المُجمَّعة، لكن قد تغلق الخوادم الاتصالات الخاملة، وفي هذه الحالة ستُزال من المُجمَّع وسيُجرى اتصال جديد عند إجراء طلب HTTP جديد لهذا المضيف والمنفذ. قد ترفض الخوادم أيضًا السماح بطلبات متعددة عبر نفس الاتصال، وفي هذه الحالة يجب إعادة إجراء الاتصال لكل طلب ولا يمكن تجميعه. وسيستمر Agent في تقديم الطلبات إلى ذلك الخادم، ولكن سيحدث كلٌ منها عبر اتصال جديد.

عند إغلاق اتصال من قبل العميل أو الخادم، يتم إزالته من التجمع. سيُلغى أي مقبس غير مستخدم في التجمع حتى لا تُشغل عملية Node.js عند عدم وجود طلبات معلقة. (راجع socket.unref()‎).

من الممارسات الجيدة، استخدام destroy()‎ لهدم مثيل الوكيل Agent عند الانتهاء من استخدامه، لأن المقابس غير المستخدمة تستهلك موارد نظام التشغيل.

تُزال المقابس من الوكيل عندما يصدر المقبس إما حدث 'close' أو حدث 'agentRemove'. عند الرغبة في الاحتفاظ بطلب HTTP واحد مفتوح لفترة طويلة دون حفظه في الوكيل، يمكن تنفيذ ما يلي:

http.get(options, (res) => {
  // أداء شيئًا ما
}).on('socket', (socket) => {
  socket.emit('agentRemove');
});

يمكن استخدام الوكيل أيضًا لطلب فردي. وذلك بتمرير {agent: false} كخيار للدالة http.get()‎ أو الدالة http.request()‎، يستخدم Agent الاستخدام لمرة واحدة مع الخيارات الافتراضية لاتصال العميل. agent:false:

http.get({
  hostname: 'localhost',
  port: 80,
  path: '/',
  agent: false  // إنشاء وكيل جديد فقط لهذا الطلب
}, (res) => {
  // أداء اشياء مع الاستجابة
});

new Agent([options])‎

أُضيف مع الإصدار: v0.3.4.

  • options من النوع <Object>: وهي مجموعة من الخيارات القابلة للتهيئة لضبط الوكيل. يمكن أن يكون لها الحقول التالية:
    • keepAlive: من النوع <boolean> ويحفظ المقابس حتى عندما لا تكون هناك طلبات معلقة، بحيث يمكن استخدامها للطلبات المستقبلية دون الحاجة إلى إعادة تأسيس اتصال TCP. القيمة الافتراضية: false.
    • keepAliveMsecs: من النوع <number> عند استخدام الخيار keepAlive، يحدد التأخير الأولي لحِزم TCP Keep-Alive. وتُهمل عندما يكون الخيار keepAlive ليس false أو undefined. القيمة الافتراضية: 1000.
    • maxSockets من النوع <number> وهو العدد الأقصى من المقابس المسموح بها لكل مضيف. القيمة الإفتراضية: Infinity.
    • maxFreeSockets من النوع <number> وهو الحد الأقصى لعدد المقابس المتروكة في حالة حرة. ويكون ذو صلة فقط إذا ضُبطت keepAlive بالقيمة true. القيمة الإفتراضية: 256.

الوكيل http.globalAgent الافتراضي المُستخدم بواسطة http.request()‎ له جميع هذه القيم المضبوطة لإعداداتها الافتراضية.

لتهيئة أي منها يجب إنشاء http.Agent مخصص.

const http = require('http');
const keepAliveAgent = new http.Agent({ keepAlive: true });
options.agent = keepAliveAgent;
http.request(options, onResponseCallback);

agent.createConnection(options[, callback])‎

أُضيف مع الإصدار: v0.11.4.

  • options من النوع <Object>: وهي خيارات تحتوي على تفاصيل الاتصال. راجع net.createConnection()‎ لتنسيق الخيارات.
  • callback من النوع <Function>: وهي دالة رد النداء التي تستقبل المقبس المُنشأ.
  • القيمة المعادة: <net.Socket>

ينتج مقبس ودفق لاستخدامهما لطلبات HTTP.

بشكل افتراضي، هذه الدالة هي نفسها net.createConnection()‎. ومع ذلك، قد تتجاوز الوكلاء المخصصين (custom agents) هذه الطريقة في حالة الرغبة في المزيد من المرونة.

يمكن تمرير المقبس/الدفق بإحدى الطريقتين التاليتين: بإعادة المقبس/الدفق من هذه الدالة، أو عن طريق تمرير المقبس/الدفق إلى callback.

وتكون callback على الشكل (err, stream).

agent.keepSocketAlive(socket)‎

أُضيف مع الإصدار: v8.1.0.

يستدعى عند فصل socket عن الطلب ويمكن أن يستمر من خلال Agent. ويكون السلوك الافتراضي كالتالي:

socket.setKeepAlive(true, this.keepAliveMsecs);
socket.unref();
return true;

يمكن تجاوز هذا التابع بواسطة صنف فرعي معين للوكيل Agent. إذا أعاد هذا التابع قيمة false أو مثيلاتها، سيُتلف المقبس بدلاً من استمرار استخدامه مع الطلب التالي.

agent.reuseSocket(socket, request)‎

أُضيفت مع الإصدار: v8.1.0.

  • socket من النوع ‎<net.Socket>
  • request من النوع ‎<http.ClientRequest>

يُستدعى عند إرفاق socket بالطلب request بعد الاستمرار بسبب خيارات keep-alive. ويكون السلوك الافتراضي كالتالي:

socket.ref();

يمكن تجاوز هذا التابع بواسطة صنف فرعي معين للوكيل Agent.

agent.destroy()‎

أُضيفت مع الإصدار: v0.11.4.

تدمير أي مقبس قيد الاستخدام حاليًا من قبل الوكيل.

عادة ليس من الضروري القيام بذلك. ومع ذلك، في حالة استخدام وكيل مع تفعيل keepAlive، فمن الأفضل إيقاف تشغيل الوكيل بشكل صريح طالما لن يستخدم مرة أخرى. خلاف ذلك، قد يتعطل المقبس ويظل مفتوحًا لفترة طويلة قبل أن ينهيه الخادم.

agent.freeSockets

أُضيف مع الإصدار: v0.11.4.

كائن يحتوي على مصفوفات من المقابس قيد انتظار الاستخدام بواسطة الوكيل عندما يكون keepAlive مُفعلًا. لا تعدله.

agent.getName(options)‎

أُضيفت مع الإصدار: v0.11.4.

  • options من النوع <Object>: مجموعة من الخيارات التي توفر معلومات لتوليد الأسماء:
    • host من النوع <string>: اسم مجال أو عنوان IP الخاص بالخادم المّصدَر إليه الطلب.
    • port من النوع <number>: منفذ الخادم البعيد
    • localAddress من النوع <string>: وهو الواجهة المحلية لمرتبطة لإجراء اتصالات الشبكة عند إصدار الطلب.
    • family من النوع <integer>: يجب أن يكون 4 أو 6 إذا كان هذا لا يساوي undefined.
  • القيمة المعادة: من النوع <string>.

الحصول على اسم فريد لمجموعة من خيارات الطلب، لتحديد ما إذا كان يمكن إعادة استخدام الاتصال. بالنسبة إلى وكيل HTTP، يؤدي هذا إلى إعادة host:port:localAddress أو host:port:localAddress:family. بالنسبة إلى وكيل HTTPS، يشتمل الاسم على CA و cert و ciphers وخيارات HTTPS / TLS الخاصة الأخرى التي تحدد قابلية إعادة استخدام المقبس.

agent.maxFreeSockets

أُضيفت مع الإصدار: v0.11.7.

قيمته الافتراضية هي 256. بالنسبة إلى الوكلاء المُفعل لهم keepAlive، يضبط الحد الأقصى لعدد المقابس التي ستُترك مفتوحة في الحالة الحرة.

agent.maxSockets

أُضيفت مع الإصدار: v0.3.6.

قيمته الافتراضية Infinity. يحدد عدد المقابس المتزامنة التي يمكن للوكيل فتحها لكل مصدر. المصدر هو القيمة المُعادة من agent.getName()‎.

agent.requests

أُضيفت مع الإصدار: v0.5.9.

كائن يحتوي على قوائم انتظار الطلبات التي لم تُعيَّن بعد إلى مقابس. لا تعدله.

agent.sockets

أُضيفت مع الإصدار: v0.3.6.

كائن يحتوي على مصفوفات من المقابس قيد الاستخدام من قِبَل الوكيل. لا تعدله.

الصنف http.ClientRequest

أُضيف مع الإصدار: v0.1.17.

يُنشأ هذا الكائن داخليًا ويُعاد من قِبَل http.request()‎. يمثل طلب in-progress الذي تنتظر ترويسته في قائمة الانتظار. لا تزال ترويسة الصفحة قابلة للتغيير باستخدام واجهات التطبيقات setHeader(name, value)‎ و setHeader(name, value)‎ و getHeader(name)‎ و removeHeader(name)‎. وترسل الترويسة الفعلية مع مقطع البيانات الأول أو عند استدعاء request.end()‎.

للحصول على الاستجابة، يجب إضافة مستمع للحدث 'response' إلى كائن الطلب. سيُصدر 'response' من كائن الطلب عند استلام ترويسات الاستجابة. يُنفّذ الحدث 'response' مع وسيطٍ واحدٍ مثيل لرسالة http.IncomingMessage.

أثناء حدث 'response'، يمكن إضافة مُستمعات إلى كائن الاستجابة؛ خاصة للاستماع لحدث 'data'.

إذا لم يُضاف معالج 'response'، فستُتجاهَل الاستجابة تمامًا. ومع ذلك، إذا أُضيف معالج للحدث 'response'، فيجب استهلاك البيانات المُعادة من كائن الاستجابة، إما باستدعاء response.read()‎ كلما يكون هناك حدث 'readable' أو بإضافة معالج 'data' أو باستدعاء التابع ‎.resume()‎. لن يُطلَق الحدث 'end' حتى تُستهلَك البيانات. أضف إلى ذلك أنَّه حتى تُقرَأ البيانات سوف تستهلك الذاكرة التي يمكن أن تؤدي في النهاية إلى خطأ "process out of memory".

لا يتحقق Node.js من تساوي طول المحتوى وطول المتن (body) المُرسل أم لا.

ينفذ الطلبُ واجهةَ التدفق القابل للكتابة. وهو EventEmitter مع الأحداث التالية:

الحدث 'abort'

أُضيف مع الإصدار: v1.4.1.

يُطلَق عند إلغاء الطلب من قِبَل العميل. يُرسل هذا الحدث فقط عند الاستدعاء الأول للدالة abort()‎.

الحدث 'connect'

أُضيف مع الإصدار: v0.7.0.

  • response من النوع ‎<http.IncomingMessage>‎.
  • socket من النوع ‎<net.Socket>‎.
  • head من النوع <Buffer>.

يُطلَق في كل مرة يستجيب فيها الخادم لطلب باستخدام الطريقة CONNECT. إذا لم يُستمَع إلى هذا الحدث، فستُغلق الاتصالات الخاصة بالعملاء الذين يتلقون طريقة CONNECT.

فيما يلي زوج من العميل والخادم يوضح كيفية الاستماع إلى الحدث 'connect':

const http = require('http');
const net = require('net');
const url = require('url');

// إنشاء وكيل HTTP نفقي
const proxy = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('okay');
});
proxy.on('connect', (req, cltSocket, head) => {
// الاتصال بخادم الأصل
  const srvUrl = url.parse(`http://${req.url}`);
  const srvSocket = net.connect(srvUrl.port, srvUrl.hostname, () => {
    cltSocket.write('HTTP/1.1 200 Connection Established\r\n' +
                    'Proxy-agent: Node.js-Proxy\r\n' +
                    '\r\n');
    srvSocket.write(head);
    srvSocket.pipe(cltSocket);
    cltSocket.pipe(srvSocket);
  });
});

// الآن هذا الوكيل يعمل
proxy.listen(1337, '127.0.0.1', () => {

// تقديم طلب إلى وكيل نفقي
  const options = {
    port: 1337,
    hostname: '127.0.0.1',
    method: 'CONNECT',
    path: 'www.google.com:80'
  };

  const req = http.request(options);
  req.end();

  req.on('connect', (res, socket, head) => {
    console.log('got connected!');

// تقديم طلب عبر نفق HTTP
    socket.write('GET / HTTP/1.1\r\n' +
                 'Host: www.google.com:80\r\n' +
                 'Connection: close\r\n' +
                 '\r\n');
    socket.on('data', (chunk) => {
      console.log(chunk.toString());
    });
    socket.on('end', () => {
      proxy.close();
    });
  });
});

الحدث 'continue'

أُضيف مع الإصدار: v0.3.2.

يُطلَق عندما يرسل خادم HTTP استجابة ‎'100 Continue'‎، عادةً بسبب احتواء الطلب على 'Expect: 100-continue' هذه تعليمة بوجوب إرسال العميل لمتن الطلب.

الحدث 'information'

أُضيف مع الإصدار: v10.0.0.

يُطلَق عندما يرسل الخادم استجابة 1xx (باستثناء 101‎ Upgrade). يُرسل هذا الحدث مع دالة رد نداء تحتوي على كائن برمز الحالة.

const http = require('http');

const options = {
  hostname: '127.0.0.1',
  port: 8080,
  path: '/length_request'
};

// تقديم طلب
const req = http.request(options);
req.end();

req.on('information', (res) => {
  console.log(`Got information prior to main response: ${res.statusCode}`);
});

لا تؤدي حالات ‎101 Upgrade إلى إطلاق هذا الحدث بسبب انقطاعها عن سلسلة طلب/استجابة HTTP التقليدية، مثل مقابس الويب أو ترقيات طبقة النقل الآمنة TLS في الموقع (in-place TLS upgrades) أو HTTP 2.0. للإشعار بالحالة 101‎ Upgrade، يجب الاستماع إلى الحدث 'upgrade' بدلاً من ذلك.

الحدث 'response'

أُضيف مع الإصدار: v0.1.0.

  • response من النوع ‎<http.IncomingMessage>‎.

يُطلَق عند تلقي استجابة لهذا الطلب. هذا الحدث يُطلَق مرة واحدة فقط.

الحدث 'socket'

أُضيف مع الإصدار: v0.5.3.

يُطلَق بعد تعيين مقبس لهذا الطلب.

الحدث 'timeout'

أُضيف مع الإصدار: v0.7.8.

يُطلَق عندما يخرج المقبس الأساسي من حالة الخمول. يصدر هذا الحدث إشعارًا بأن النفس حامل. يجب إلغاء الطلب يدويًا.

انظر أيضًا: request.setTimeout()‎.

الحدث: 'upgrade'

أُضيف مع الإصدار: v0.1.94.

  • response من النوع ‎<http.IncomingMessage>‎.
  • socket من النوع ‎<net.Socket>‎.
  • head من النوع ‎<Buffer>‎.

يُطلَق في كل مرة يستجيب فيها الخادم لطلب ما باستخدام ترقية (upgrade). إذا لم يُستمع لهذا الحدث وكان رمز حالة الاستجابة هو ‎101 Switching Protocols، فستُغلق اتصالات العملاء التي تتلقى ترويسة ترقية.

فيما يلي يوضح زوج الخادم والعميل كيفية الاستماع لحدث 'upgrade'.

const http = require('http');

// إنشاء خادم HTTP
const srv = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('okay');
});
srv.on('upgrade', (req, socket, head) => {
  socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
               'Upgrade: WebSocket\r\n' +
               'Connection: Upgrade\r\n' +
               '\r\n');

  socket.pipe(socket); // echo back
});

// الآن هذا الخادم يعمل
srv.listen(1337, '127.0.0.1', () => {

// تقديم طلب
  const options = {
    port: 1337,
    hostname: '127.0.0.1',
    headers: {
      'Connection': 'Upgrade',
      'Upgrade': 'websocket'
    }
  };

  const req = http.request(options);
  req.end();

  req.on('upgrade', (res, socket, upgradeHead) => {
    console.log('got upgraded!');
    socket.end();
    process.exit(0);
  });
});

request.abort()‎

أُضيفت مع الإصدار: v0.3.8.

يحدد الطلب على أنه جارٍ إلغاؤه. يؤدي استدعاء هذا إلى إسقاط البيانات المتبقية في الاستجابة وهدم المقبس.

request.aborted

أُضيفت مع الإصدار: v0.11.14.

إذا أُلغي طلب، تصبح هذه القيمة هي الوقت الذي أُحبِط فيه الطلب، بالمللي ثانية منذ 1 كانون الثاني/يناير ‎1970 00:00:00 UTC.

request.connection

أُضيفت مع الإصدار: v0.3.0.

راجع request.socket.

request.end([data[, encoding]][, callback])‎

سجل التغييرات

الإصدار التغييرات
v10.0.0 يعيد هذا التابع الآن مرجع إلى ClientRequest.
v0.1.90 أُضيفت مع الإصدار: v0.1.90.

الانتهاء من إرسال الطلب. إذا لم يُرسَل أي جزء من المتن، فسيرسله إلى التدفق. إذا قُسِّم الطلب، فسيؤدي ذلك إلى إرسال ‎'0\r\n\r\n'‎.

إذا حُدِدت data، فإنه يكافئ استدعاء request.write(data, encoding)‎ متبوعًا بالتابع request.end(callback)‎.

إذا حُدِدت الدالة callback، فستُستدعى عند انتهاء تدفق الطلب.

request.flushHeaders()‎

أُضيف مع الإصدار: v1.6.0.

دفق ترويسات الطلبات.

لأسباب تتعلق بالكفاءة، عادةً ما يخزن Node.js ترويسات الطلبات مؤقتًا حتى يُستدعى request.end()‎ أو يُكتب أول جزء من بيانات الطلب. ثم يحاول حزم ترويسات الطلب والبيانات في حزمة TCP واحدة.

عادة ما يكون ذلك مرغوبًا (فهو يحفظ رحلة ذهاب وإياب TCP)، ولكن ليس عند عدم إرسال البيانات الأولى حتى وقت لاحق. يتجاوز request.flushHeaders()‎ هذا التحسين ويبدأ الطلب.

request.getHeader(name)‎

أُضيف مع الإصدار: v1.6.0.

  • name من النوع <string>.
  • القيمة المعادة: أي نوع من الأنواع.

يقرأ ترويسة الطلب. لاحظ أن الاسم غير حساس لحالة الأحرف. يعتمد نوع القيمة المعادة على الوسائط المُمررة إلى request.setHeader()‎.

أمثلة

request.setHeader('content-type', 'text/html');
request.setHeader('Content-Length', Buffer.byteLength(body));
request.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
const contentType = request.getHeader('Content-Type');
// contentType is 'text/html'
const contentLength = request.getHeader('Content-Length');
// contentLength is of type number
const setCookie = request.getHeader('set-cookie');
// setCookie is of type string[]

request.maxHeadersCount

  • <number> القيمة الإفتراضية: 2000

يحدد عدد ترويسات الاستجابات القصوى. إذا ضُبِط بالقيمة 0، فلن يُطبَّق أي حد.

request.removeHeader(name)‎

أُضيف مع الإصدار: v1.6.0.

يزيل ترويسة معرفة بالفعل في كائن الترويسات.

أمثلة

request.removeHeader('Content-Type');

request.setHeader(name, value)‎

أُضيف مع الإصدار: v1.6.0.

  • name من النوع <string>.
  • value من أي نوع من الأنواع.

ضبط قيمة ترويسة واحدة لكائن الترويسات. إذا كانت هذه الترويسة موجودةً بالفعل في الترويسات التي ستُرسَل، فستُستبدَل قيمتها. وهي تستخدم هنا مصفوفة من السلاسل النصية لإرسال عدة ترويسات تحمل نفس الاسم. ستُتخزن القيم غير النصية بدون تعديل. لذلك، قد يُعيد request.getHeader()‎ قيم ليست سلسلةً نصيةً. ومع ذلك، ستُحوّل القيم غير النصية إلى سلاسل نصية كي تُنقل على الشبكة.

أمثلة

request.setHeader('Content-Type', 'application/json');

أو

request.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);

request.setNoDelay([noDelay])‎

أُضيفت مع الإصدار: v0.5.9.

بمجرد تعيين مأخذ توصيل لهذا الطلب ستُستدعى socket.setNoDelay()‎.

request.setSocketKeepAlive([enable][, initialDelay])‎

أُضيفت مع الإصدار: v0.5.9.

بمجرد تعيين مقبس لهذا الطلب وهو متصل ستُستدعى الدالة socket.setKeepAlive()‎.

request.setTimeout(timeout[, callback])‎

أُضيفت مع الإصدار: v0.5.9.

  • timeout من النوع <number> وهو الوقت بالميلي ثانية قبل إنتهاء مهلة الطلب.
  • callback من النوع <Function> وهي دالة اختيارية تُستدعى عند انقضاء المهلة. بنفس الارتباط بحدث 'timeout'.
  • القيمة المُعادة: <http.ClientRequest>

بمجرد تعيين مقبس لهذا الطلب وتوصيلها ستُستدعى الدالة socket.setTimeout()‎.

request.socket

أُضيفت مع الإصدار: v0.3.0.

يُشير إلى المقبس الأساسي. عادة لا يرغب المستخدمون في الاقتراب من هذه الخاصية. على وجه الخصوص، لن يُصدر المقبس أحداث 'readable' بسبب كيفية توصيل مُحلل البروتوكول بالمقبس. يمكن أيضًا الوصول إلى socket من خلال request.connection.

أمثلة

const http = require('http');
const options = {
  host: 'www.google.com',
};
const req = http.get(options);
req.end();
req.once('response', (res) => {
  const ip = req.socket.localAddress;
  const port = req.socket.localPort;
  console.log(`Your IP address is ${ip} and your source port is ${port}.`);
// استهلاك كائن الاستجابة
});

request.write(chunk[, encoding][, callback])‎

أُضيف مع الإصدار: v0.1.29.

إرسال قطعة من المتن. من خلال استدعاء هذه الدالة عدة مرات، يمكن إرسال متن طلب إلى خادم - في هذه الحالة، يُقترح استخدام سطر الترويسة ['Transfer-Encoding', 'chunked'] عند إنشاء الطلب.

يُعد الوسيط encoding اختياريًا وينطبق فقط عندما يكون chunk سلسلة نصية. وقيمته الافتراضية 'utf8'.

كما يُعد الوسيط callback اختياريًا ويُستدعى عند دفع جزء البيانات هذا.

وتعيد هذه الدالة true إذا دُفِعت البيانات بالكامل بنجاح إلى المخزن المؤقت kernel. وتعيد false إذا وضعت كل البيانات أو جزء منها في قائمة الانتظار في ذاكرة المستخدم. سوف يُطلَق الحدث 'drain' عندما يكون المخزن المؤقت متاحًا مرة أخرى.

الصنف http.Server

أُضيف مع الإصدار: v0.1.17.

يرث هذا الصنف من net.Server ولديه الأحداث الإضافية التالية:

الحدث 'checkContinue'

أُضيف مع الإصدار: v0.3.0.

  • request من النوع ‎<http.IncomingMessage>‎.
  • response من النوع ‎<http.ServerResponse>‎.

يُطلَق عند استقبال طلب HTTP مع Expect: 100-continue. إذا لم يُستمع إلى هذا الحدث، فسيستجيب الخادم تلقائيًا بترويسة 100‎ Continue حسب الاقتضاء.

تتضمن معالجة هذا الحدث استدعاء response.writeContinue()‎ إذا استمر العميل في إرسال متن الطلب أو إنشاء استجابة HTTP مناسبة (على سبيل المثال 400‎ Bad Request) إذا كان العميل لا يجب أن يستمر في إرسال متن الطلب.

لاحظ أنه عند إطلاق هذا الحدث ومعالجته، لن يُطلَق حدث 'request'.

الحدث: 'checkExpectation'

أُضيف مع الإصدار: v5.5.0.

  • request من النوع ‎<http.IncomingMessage>‎.
  • response من النوع ‎<http.ServerResponse>‎.

يُطلَق عند استقبال طلب مع ترويسة HTTP Expect، بحيث تكون القيمة غير 100‎ Continue. إذا لم يُستمع إلى هذا الحدث، فسيستجيب الخادم تلقائيًا مع ‎417 Expectation Failed حسب الاقتضاء.

لاحظ أنه عند انطلاق هذا الحدث ومعالجته، لن يُطلَق حدث 'request'.

الحدث 'clientError'

سجل التغييرات

الإصدار التغييرات
v9.4.0 rawPacket هو المخزن المؤقت الحالي الذي يُحلَّل فقط. إضافة هذا المخزن المؤقت إلى كائن الخطأ للحدث 'clientError' يُعد بمثابة تمكين للمطورين لتسجيل الحزمة المعطلة.
v6.0.0 لن يحدث الإجراء الافتراضي للاتصال بالدالة ‎.destroy()‎ على socket إذا كان هناك مُستمعات مرتبطة بالحدث 'clientError'.
v0.1.94 أُضيفت مع الإصدار: v0.1.94

إذا أطلق اتصال العميل حدث 'error'، فسيُعاد توجيهه هنا. ويُعد مستمع هذا الحدث هو المسؤول عن إغلاق وهدم المقبس الأساسي. على سبيل المثال، قد يرغب المرء في إغلاق المقبس بأمان مع استجابة HTTP مخصصة بدلاً من قطع الاتصال فجأة.

السلوك الافتراضي هو إغلاق المقبس باستجابة HTTP '‎400 Bad Request'‎ إن أمكن، وإلا يُهدم المقبس فورًا.

socket هو كائن net.Socket الذي نشأ الخطأ منه.

const http = require('http');

const server = http.createServer((req, res) => {
  res.end();
});
server.on('clientError', (err, socket) => {
  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.listen(8000);

عند حدوث الحدث 'clientError'، لا يوجد كائن request أو response، لذلك يجب كتابة أي استجابة HTTP أُرسِلت، بما في ذلك ترويسات الاستجابة والحمولة، مباشرةً إلى كائن socket. يجب توخي الحذر لضمان أن الاستجابة هي رسالة استجابة HTTP منسقة بشكل صحيح.

err هو مثيل للحدث Error مع عمودين إضافيين:

  • bytesParsed: عدد وحدات البايت الخاصة بحزمة الطلب التي قد يكون حللها Node.js بشكل صحيح؛
  • rawPacket: الحزمة الأولية للطلب الحالي.

الحدث 'close'

أُضيف مع الإصدار: v0.1.4.

يُطلَق عند إغلاق الخادم.

الحدث 'connect'

أُضيف مع الإصدار: v0.7.0.

  • request من النوع ‎<http.IncomingMessage>‎: وسائط لطلب HTTP، كما هو الحال في حدث 'request'.
  • socket من النوع <net.Socket>: مقبس الشبكة بين الخادم والعميل.
  • head من النوع ‎<Buffer>‎: أول حزمة من الدفق النفقي (قد تكون فارغة).

يُطلَق في كل مرة يطلب فيها العميل طريقة HTTP CONNECT. إذا لم يُستمع إلى هذا الحدث، فستُغلق اتصالات العملاء التي تطلب الطريقة CONNECT.

بعد إطلاق هذا الحدث، لن يكون لمقبس الطلب مستمع حدث 'data'، مما يعني أنه سيكون من الضروري الارتباط من أجل معالجة البيانات المُرسلة إلى الخادم على هذا المقبس.

الحدث 'connection'

أُضيف مع الإصدار: v0.1.0.

يُطلَق هذا الحدث عند تأسيس دفق TCP جديد. عادةً ما يكون socket كائنًا من النوع net.Socket. عادة لا يرغب المستخدمون في استخدام هذا الحدث. على وجه الخصوص، لن يُصدر المقبس أحداث 'readable' بسبب كيفية توصيل مُحلل البروتوكول بالمقبس. يمكن أيضا الوصول إلى socket عند request.connection.

يمكن أيضًا أن يُطلَق هذا الحدث صراحةً من قِبل المستخدمين لإدخال اتصالات في خادم HTTP. في هذه الحالة، يمكن تمرير أي دفق Duplex.

الحدث 'request'

أُضيف مع الإصدار: v0.1.0.

  • request من النوع <http.IncomingMessage>.
  • response من النوع <http.ServerResponse>.

يُطلَق عند كل طلب. لاحظ أنه قد يكون هناك عدة طلبات لكل اتصال (في حالة اتصالات HTTP Keep-Alive).

الحدث: 'upgrade'

سجل التغييرات

الإصدار التغييرات
v10.0.0 عدم الاستماع إلى هذا الحدث لم يعد يتسبب في هدم المقبس إذا أرسل عميل ترويسة ترقية Upgrade.
v0.1.94 أُضيفت مع الإصدار: v0.1.94
  • request من النوع <http.IncomingMessage>: وسائط لطلب HTTP، كما هو الحال في حدث 'request'.
  • socket من النوع ‎<net.Socket>‎: مقبس الشبكة بين الخادم والعميل.
  • head من النوع <Buffer>: أول حزمة من الدفق المُرقَّى (قد يكون فارغًا).

يُطلَق في كل مرة يطلب فيها العميل ترقية HTTP. يُعد الاستماع إلى هذا الحدث اختياريًا ولا يمكن للعملاء الإصرار على تغيير البروتوكول.

بعد إطلاق هذا الحدث، لن يكون لمقبس الطلب مستمع حدث 'data'، مما يعني أنه سيكون من الضروري الارتباط من أجل معالجة البيانات المُرسلة إلى الخادم على هذا المقبس.

server.close([callback])‎

أُضيف مع الإصدار: v0.1.90.

إيقاف الخادم عن قبول اتصالات جديدة. راجع net.Server.close()‎.

server.listen()‎

بدء استماع خادم HTTP للاتصالات. هذه الدالة مماثلة للدالة server.listen()‎ من net.Server.

server.listening

أُضيفت مع الإصدار: v5.7.0.

  • <boolean> يشير إلى ما إذا كان الخادم يستمع للاتصالات أم لا.

server.maxHeadersCount

أُضيفت مع الإصدار: v0.7.0.

  • <number> القيمة الإفتراضية: 2000.

يُحدد الحد الأقصى للترويسات الواردة. إذا ضُبِط بالقيمة 0، فلن يُطبَّق أي حد.

server.setTimeout([msecs][, callback])‎

أُضيفت مع الإصدار: v0.9.12.

  • msecs من النوع <number> القيمة الإفتراضية: 120000 (2 دقيقة).
  • callback من النوع <Function>.
  • القيمة المُعادة: <http.Server>.

يضبط قيمة المهلة للمآخذ، ويطلق حدث 'timeout' على كائن الخادم، ويمرر المقبس كوسيط، في حالة انتهاء المهلة.

إذا كان هناك مستمع حدث 'timeout' على كائن الخادم، فسيُستدعى مع المقبس المنتهي مهلته. كوسيط.

بشكل افتراضي، تكون قيمة مهلة الخادم دقيقتين، وتهدم المقابس تلقائيًا عند انتهاء مهلتها. ومع ذلك، إذا عُينت دالة رد نداء لحدث 'timeout' الخاص بالخادم، فيجب التعامل مع المُهلات بشكل صريح.

server.timeout

أُضيفت مع الإصدار: v0.9.12.

  • <number> المهلة بالمللي ثانية. القيمة الإفتراضية: 120000 (2 دقيقة).

الوقت بالميلي ثانية من الخمول قبل اعتبار أن المقبس قد انتهت مهلته.

إذا كانت القيمة تساوي 0 سيتعطل سلوك المهلة مع الاتصالات الواردة.

منطق مهلة المقبس مبني على الاتصال، لذا فإن تغيير هذه القيمة يؤثر فقط على الاتصالات الجديدة بالخادم، وليس أي اتصالات موجودة.

server.keepAliveTimeout

أُضيفت مع الإصدار: v8.0.0.

  • <number> المهلة بالمللي ثانية. القيمة الإفتراضية: 5000 (5 ثوان).

الوقت بالمللي ثانية من الخمول والذي يحتاجه الخادم لانتظار بيانات واردة إضافية، بعد الانتهاء من كتابة الاستجابة الأخيرة، قبل هدم المقبس. إذا تلقى الخادم بيانات جديدة قبل إطلاق مهلة keep-alive، سيُعيد تعيين مهلة الخمول المعتادة، أي server.timeout.

إذا كانت القيمة تساوي 0 سيتعطل سلوك مهلة keep-alive مع الاتصالات الواردة. تجعل القيمة 0 الخادم http يتصرف بشكل مشابه للإصدارات Node.js قبل 8.0.0، التي لم يكن بها مهلة keep-alive.

منطق مهلة المقبس مبني على الاتصال، لذا فإن تغيير هذه القيمة يؤثر فقط على الاتصالات الجديدة بالخادم، وليس أي اتصالات موجودة.

الصنف http.ServerResponse

أُضيف مع الإصدار: v0.1.17.

يُنشأ هذا الكائن داخليًا بواسطة خادم HTTP - وليس من قبل المستخدم. ويُمرر كمعامل ثاني لحدث 'request'.

تنفِذ الاستجابة، ولكن لا ترث من، واجهة الدفق القابل للكتابة. وهو مُطلق أحداث EventEmitter للأحداث التالية:

الحدث 'close'

أُضيف مع الإصدار: v0.6.7.

يشير إلى إنهاء الاتصال الأساسي.

الحدث 'finish'

أُضيف مع الإصدار: v0.3.6.

يُطلَق عند إرسال الاستجابة. وبشكل أكثر تحديدًا، يُطلَق هذا الحدث عند تسليم الجزء الأخير من ترويسات الاستجابة والمتن إلى نظام التشغيل للإرسال عبر الشبكة. ولا يعني ذلك أن العميل قد تلقى أي شيء حتى الآن.

بعد هذا الحدث، لن تُرسل أي أحداث أخرى على كائن الاستجابة.

response.addTrailers(headers)‎

أُضيف مع الإصدار: v0.3.0.

تضيف هذه الدالة ترويسات HTTP اللاحقة (هي ترويسات ولكن توجد في نهاية الرسالة) إلى الاستجابة.

لن تُصدَر الترويسات اللاحقة إلا إذا اُستخدِم التشفير المقسم للاستجابة؛ وإذا لم يُستُخدم (على سبيل المثال إذا كان الطلب HTTP / 1.0)، ستُتجاهل بهدوء.

لاحظ أن HTTP يتطلب إرسال ترويسة Trailer لإصدار اللواحق، مع قائمة بحقول الترويسة في قيمتها. على سبيل المثال:

response.writeHead(200, { 'Content-Type': 'text/plain',
                          'Trailer': 'Content-MD5' });
response.write(fileData);
response.addTrailers({ 'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667' });
response.end();

ستؤدي محاولة ضبط اسم حقل ترويسة أو قيمته والتي يحتويان على أحرف غير صالحة إلى ظهور TypeError.

response.connection

أُضيفت مع الإصدار: v0.3.0.

انظر response.socket.

response.end([data][, encoding][, callback])‎

سجل التغييرات

الإصدار التغييرات
v10.0.0 يُعيد هذا التابع الآن مرجع إلى ServerResponse.
v0.1.90 أُضيف مع الإصدار: v0.1.90.

تشير هذه الدالة إلى الخادم أن كل ترويسات الاستجابة والمتن قد أُرسِلَت؛ وأن يجب على الخادم اعتبار أن الرسالة قد اكتملت. يجب استدعاء التابع response.end()‎ عند كل استجابة.

إذا حُدِدت قيمة data، فإنه يعادل استدعاء التابع response.write(data, encoding)‎ متبوعًا بالتابع response.end(callback)‎.

إذا حُدِدت دالة callback، فستُستدعى عند انتهاء تدفق الاستجابة.

response.finished

أُضيفت مع الإصدار: v0.0.2.

قيمة منطقية تشير إلى ما إذا كانت الاستجابة قد اكتملت. تبدأ بالقيمة false. وبعد تنفيذ response.end()‎، تصبح القيمة true.

response.getHeader(name)‎

أُضيفت مع الإصدار: v0.4.0.

  • name من النوع <string>.
  • القيمة المُعادة: أي نوع من الأنواع.

تقرأ ترويسة موضوعة في قائمة الانتظار بالفعل ولكن لم تُرسَل إلى العميل. لاحظ أن الاسم غير حساس لحالة الأحرف. يعتمد نوع القيمة المُعادة على الوسائط المُمررة إلى response.setHeader()‎.

أمثلة

response.setHeader('Content-Type', 'text/html');
response.setHeader('Content-Length', Buffer.byteLength(body));
response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
const contentType = response.getHeader('content-type');
// contentType هو 'text/html'
const contentLength = response.getHeader('Content-Length');
// contentLength من التوع number
const setCookie = response.getHeader('set-cookie');
// setCookie من النوع string[]

response.getHeaderNames()‎

أُضيفت مع الإصدار: v7.7.0.

تُعيد مصفوفة تحتوي على الأسماء الفريدة للترويسات الصادرة الحالية. كل أسماء الترويسات تكتب بالأحرف الصغيرة.

أمثلة

response.setHeader('Foo', 'bar');
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);

const headerNames = response.getHeaderNames();
// headerNames === ['foo', 'set-cookie']

response.getHeaders()‎

أُضيفت مع الإصدار: v7.7.0.

  • القيمة المُعادة: <Object>.

تعرض هذه الدالة نسخة ضحلة من الترويسات الصادرة الحالية. نظرًا لاستخدام نسخة ضحلة، فقد تتحور قيم المصفوفة بدون استدعاءات إضافية للعديد من دوال وحدات http ذات الصلة بالترويسة. مفاتيح الكائن المُعاد هي أسماء الترويسات والقيم هي قيم الترويسات المناظرة كل منها. كل أسماء العناوين تكتب بالأحرف الصغيرة.

لا يرث الكائن المُعاد من الدالة response.getHeaders()‎ بشكل نمطي من Object الـ JavaScript. هذا يعني أن دوال Object الموروثة عبر سلسلة prototype مثل obj.toString()‎ و obj.hasOwnProperty()‎، وغيرها لم تُعرَّف ولن تعمل.

أمثلة

response.setHeader('Foo', 'bar');
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);

const headers = response.getHeaders();
// headers === { foo: 'bar', 'set-cookie': ['foo=bar', 'bar=baz'] }

response.hasHeader(name)‎

أُضيفت مع الإصدار: v7.7.0.

  • name من النوع <string>.
  • القيمة المعادة: من النوع <boolean>.

تُعيد true إذا ضُبِطت الترويسة المُعرَفة بواسطة الاسم name حاليًا في الترويسات الصادرة. لاحظ أن مطابقة اسم الترويسة غير حساس لحالة الأحرف.

أمثلة

const hasContentType = response.hasHeader('content-type');

response.headersSent

أُضيفت مع الإصدار: v0.9.3.

قيمة منطقية (للقراءة فقط). وتكون True إذا أُرسلت الترويسات، و False خلاف ذلك.

response.removeHeader(name)‎

أُضيفت مع الإصدار: v0.4.0.

إزالة ترويسة مدرجة في قائمة الانتظار للإرسال الضمني.

أمثلة

response.removeHeader('Content-Encoding');

response.sendDate

أُضيفت مع الإصدار: v0.7.5.

عندما تكون قيمتها True، تُنشَئ ترويسة التاريخ تلقائيًا وتُرسَل في الإستجابة إذا لم يكن موجودًا بالفعل في الترويسات. قيمتها الافتراضية True.

يجب تعطيلها فقط للاختبار. إذ يتطلب HTTP ترويسة التاريخ في الإستجابات.

response.setHeader(name, value)‎

أُضيفت مع الإصدار: v0.4.0.

  • name من النوع <string>.
  • value من أي نوع من الأنواع.

ضبط قيمة الترويسات الضمنية بقيمة ترويسة واحدة. إذا كانت هذه الترويسة موجودة بالفعل في الترويسات التي ستُرسل، فستُستبدل قيمتها. وهي تستخدم هنا مصفوفة من السلاسل النصية لإرسال عدة ترويسات تحمل نفس الاسم. ستُتخزن القيم غير النصية بدون تعديل. لذلك، قد تُعيد response.getHeader()‎ قيم غير نصية. ومع ذلك، ستُحوّل القيم غير النصية إلى سلاسل نصية كي تُنقل على الشبكة.

أمثلة

response.setHeader('Content-Type', 'text/html');

أو

response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);

ستؤدي محاولة ضبط اسم حقل ترويسة أو قيمته والتي يحتويان على أحرف غير صالحة إلى ظهور TypeError. عند ضبط الترويسات باستخدام response.setHeader()‎، ستُدمج مع أي ترويسات تُمرر إلى response.writeHead()‎، مع أسبقية الترويسات المُمررة إلىresponse.writeHead()‎.

// إعادة content-type = text/plain
const server = http.createServer((req, res) => {
  res.setHeader('Content-Type', 'text/html');
  res.setHeader('X-Foo', 'bar');
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('ok');
});

response.setTimeout(msecs[, callback])‎

أُضيفت مع الإصدار: v0.9.12.

  • msecs من النوع <number>.
  • callback من النوع <Function>.
  • القيمة المُعادة: <http.ServerResponse>.

ضبط msecs بقيمة مهلة المقبس. إذا توفَّرت دالة رد النداء، فسيُضاف كمستمع في الحدث 'timeout' على كائن الاستجابة.

إذا لم يُضاف أي مستمع 'timeout' إلى الطلب أو الاستجابة أو الخادم، فستُهدم المقابس عند إنتهاء المهلة. إذا عُيّن معالج إلى أحداث 'timeout' الخاصة بالطلب، أو بالإستجابة أو بالخادم، يجب معالجة المقابس المنتهية مهلتها بشكل صريح.

response.socket

أُضيفت مع الإصدار: v0.3.0.

الإشارة إلى المقبس الأساسي. عادة لا يرغب المستخدمون في الاقتراب من هذه الخاصية. على وجه الخصوص، لن يُصدر المقبس أحداث 'readable' بسبب كيفية توصيل مُحلل البروتوكول بالمقبس. بعد response.end()‎، تُلغى الخاصية. يمكن الوصول إلى socket أيضًا عبر response.connection.

أمثلة

const http = require('http');
const server = http.createServer((req, res) => {
  const ip = res.socket.remoteAddress;
  const port = res.socket.remotePort;
  res.end(`Your IP address is ${ip} and your source port is ${port}.`);
}).listen(3000);

response.statusCode

أُضيفت مع الإصدار: v0.4.0.

عند استخدام الترويسات الضمنية (عدم استدعاء response.writeHead()‎ بشكل صريح)، تتحكم هذه الخاصية في رمز الحالة الذي سيُرسَل إلى العميل عند دفع الترويسات.

أمثلة

response.statusCode = 404;

بعد إرسال ترويسة الاستجابة إلى العميل، تشير هذه الخاصية إلى رمز الحالة الذي أُرسِل.

response.statusMessage

أُضيفت مع الإصدار: v0.11.8.

عند استخدام الترويسات الضمنية (عدم استدعاء response.writeHead()‎ بشكل صريح)، تتحكم هذه الخاصية في رسالة الحالة التي ستُرسل إلى العميل عند دفع الترويسات. إذا تُرِكت على أنها undefined فستُستخدم الرسالة القياسية لرمز الحالة.

أمثلة

response.statusMessage = 'Not found';

بعد إرسال ترويسة الاستجابة إلى العميل، تشير هذه الخاصية إلى رسالة الحالة التي أُرسِلت.

response.write(chunk[, encoding][, callback])‎

أُضيفت مع الإصدار: v0.1.29.

  • chunk من النوع ‎<string> | <Buffer>‎‎.
  • Encoding من النوع <string>، وقيمته الإفتراضية: 'utf8'.
  • callback من النوع <Function>.
  • القيمة المعادة: <boolean>.

عند استدعاء هذه الدالة وعدم استدعاء response.writeHead()‎ مسبقًا، فستنتقل إلى وضع الترويسة الضمنية وتدفع الترويسات الضمنية.

يرسل هذا جزءًا من متن الاستجابة. يمكن استدعاء هذه الدالة عدة مرات للإمداد بأجزاء متتالية من المتن.

لاحظ أنه في وحدة http، يُحذف نص الاستجابة عندما يكون الطلب هو طلب للترويسة HEAD. وبالمثل، يجب ألا تتضمن الاستجابات 204 و 304 متنَ رسالة.

يمكن أن يكون chunk سلسلة نصية أو مخزن مؤقت. إذا كان chunk سلسلة نصية، يحدد الوسيط الثاني كيفية ترميزه في دفق ثنائي. شتُستدعى دالة callback عند دفع جزء البيانات هذا.

وهو متن HTTP الأولي ولا علاقة له بترميزات المتن متعدد الأجزاء ذي المستوى الأعلى التي يمكن استخدامها.

عند استدعاء response.write()‎ لأول مرة، يُرسل معلومات ترويسة الموجودة في المخزن المؤقت والجزء الأول من المتن إلى العميل. وعند استدعاء response.write()‎ للمرة الثانية، يفترض Node.js تدفق البيانات وإرسال البيانات الجديدة بشكل منفصل. بمعنى، تُخزَّن الاستجابة حتى الجزء الأول من المتن.

تُعيد true إذا دُفِعت البيانات بالكامل بنجاح إلى مخزن kernel المؤقت. وتُعيد false إذا وضعت كل البيانات أو جزء منها في قائمة انتظار ذاكرة المستخدم. سوف يُطلق 'drain' عندما يكون المخزن المؤقت متاحًا مرة أخرى.

response.writeContinue()‎

أُضيف مع الإصدار: v0.3.0.

إرسال رسالة HTTP/1.1 ‎100 Continue إلى العميل، مشيرا إلى أنه يجب إرسال متن الطلب. راجع حدث 'checkContinue' على Serve‎r.

response.writeHead(statusCode[, statusMessage][, headers])‎

سجل التغييرات

الإصدار التغييرات
v5.11.0 و 4.4.4 يُطرح RangeError إذا كانت statusCode ليست عددًا ضمن النطاق [100, 999].
v0.1.30 أُضيف مع الإصدار: v0.1.30.

إرسال ترويسة استجابة إلى الطلب. رمز الحالة هو رمز حالة HTTP مكون من 3 أرقام، مثل 404. الوسيط الأخير headers هو ترويسات الاستجابة. يمكن إعطاء رسالة حالة statusMessage مقروءة كوسيط ثاني.

أمثلة

const body = 'مرحبًا أيها العالم';
response.writeHead(200, {
  'Content-Length': Buffer.byteLength(body),
  'Content-Type': 'text/plain' });

يجب استدعاء هذه الدالة مرة واحدة فقط في كل رسالة ويجب أن يكون ذلك قبل استدعاء response.end()‎.

إذا أستُدعي أيًا من response.write()‎ أو response.end()‎ قبل استدعاء هذا التابع، فستُحسب الترويسات الضمنية أو القابلة للتغيير وتستدعي هذا التابع.

عند ضبط الترويسات باستخدام response.setHeader()‎، ستُدمج مع أي ترويسات تُمرر إلى response.writeHead()‎، مع أسبقية الترويسات المُمررة إلى response.writeHead()‎.

// إعادة content-type = text/plain
const server = http.createServer((req, res) => {
  res.setHeader('Content-Type', 'text/html');
  res.setHeader('X-Foo', 'bar');
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('ok');
});

لاحظ أن طول المحتوى Content-Length مُعطى بالبايت وليس بالأحرف. فيعمل المثال أعلاه لأن السلسلة النصية 'مرحبًا أيها العالم' تحتوي على حروف مكونة من بايت واحدة فقط. إذا احتوى المتن على أحرف من ترميز أعلى، فيجب استخدام Buffer.byteLength()‎ لتحديد عدد وحدات البايت في ترميز معين. ولا يتحقق Node.js ما إذا كان Content-Length وطول المتن المُرسل متساويين أم لا.

ستؤدي محاولة ضبط اسم حقل ترويسة أو قيمته والتي يحتويان على أحرف غير صالحة إلى ظهور TypeError.

response.writeProcessing()‎

أُضيفت مع الإصدار: v10.0.0.

يرسل رسالة HTTP / 1.1 102 Processing إلى العميل، مُشيرةً إلى أنه يجب إرسال متن الطلب.

الصنف http.IncomingMessage

أُضيف مع الإصدار: v0.1.17.

إنشاء كائن IncomingMessage بواسطة http.Server أو http.ClientRequest وتمريرها كوسيط أول لحدثي 'request' و 'response' على التوالي. يمكن استخدام هذا الصنف للوصول إلى حالة الاستجابة والترويسات والبيانات.

فهي تطبق واجهة Readable Stream، بالإضافة إلى الأحداث والدوال والخصائص الإضافية التالية:

الحدث 'aborted'

أُضيف مع الإصدار: v0.3.8.

يُطلَق عند إلغاء الطلب.

الحدث 'close'

أُضيف مع الإصدار: v0.4.2.

يشير إلى أن الاتصال الأساسي قد أُغلِق. تمامًا مثلما في حالة الحدث 'end'، يحدث هذا الحدث مرة واحدة فقط لكل استجابة.

message.aborted

أُضيفت مع الإصدار: v10.1.0.

ستصبح الخاصية message.aborted بالقيمة true إذا أُلغي الطلب.

message.destroy([error])‎

أُضيفت مع الإصدار: v0.3.0.

استدعاء الدالة destroy()‎ على المقبس الذي تلقى IncomingMessage. إذا مُرِر error، يُطلَق حدث 'error' ويُمرر error كوسيط لأي مستمع في الحدث.

message.headers

أُضيفت مع الإصدار: v0.1.5.

كائن ترويسات الطلب أو الاستجابة.

أزواج القيمة الرئيسية لأسماء الترويسات وقيمها. تكون أسماء الترويسات من الأحرف الصغيرة. على سبيل المثال:

// طباعة شيئًا مثل:
//
// { 'user-agent': 'curl/7.22.0',
//   host: '127.0.0.1:8000',
//   accept: '*/*' }
console.log(request.headers);

تُعالج التكرارات في الترويسات الأولية بالطرق التالية، اعتمادًا على اسم الترويسة:

  • تُتجاهَل تكرارات كل من age وauthorization و content-length و content-type و etag و expires و from و host و if-modified-since و if-unmodified-since و last-modified و location و max-forwards و proxy-authorization و referer و retry-after و user-agent.
  • set-cookie هي دائما مصفوفة. ويضاف إليها هذه المكررات.
  • بالنسبة إلى جميع الترويسات الأخرى، تُضم القيم مع ', '.

message.httpVersion

أُضيفت مع الإصدار: v0.1.1.

في حالة طلب الخادم، يرسل العميل رقم إصدار HTTP. في حالة استجابة العميل، يرسل إصدار HTTP الخاص بالخادم المتصل. على الأغلب إما '1.1' أو '1.0'.

أيضا message.httpVersionMajor تعيد أول عدد صحيح و message.httpVersionMinor تعيد الثاني.

message.method

أُضيفت مع الإصدار: v0.1.1.

صالحة فقط للطلب المُعاد من http.Server.

إعادة طريقة الطلب كسلسلة نصية. يُقرأ فقط. مثال: 'GET' و 'DELETE'.

message.rawHeaders

أُضيفت مع الإصدار: v0.11.6.

قائمة ترويسات الطلبات والاستجابات الأولية تمامًا كما تَرِد.

لاحظ أن المفاتيح والقيم موجودة في نفس القائمة. وهي ليست قائمة من صفوف. لذا، فإن العناصر ذات الأرقام الزوجية هي قيم المفاتيح، والعناصر ذات الأرقام الفردية هي القيم المرتبطة بها.

لا تكون الترويسات مكتوبة بأحرف صغيرة ولا تُدمَج التكرارات.

// طباعة شيئًا مثل:
//
// [ 'user-agent',
//   'لا يصلح هذا لأنه لا يمكن أن يكون هناك سوى واحد',
//   'User-Agent',
//   'curl/7.22.0',
//   'Host',
//   '127.0.0.1:8000',
//   'ACCEPT',
//   '*/*' ]
console.log(request.rawHeaders);

message.rawTrailers

أُضيفت مع الإصدار: v0.11.6.

تحتوي مفاتيح وقيم الطلب والاستجابة الأولية المُلحقة كما ترِد تمامًا. تُرسل فقط عند الحدث 'end'.

message.setTimeout(msecs, callback)‎

أُضيف مع الإصدار: v0.5.9.

  • msecs من النوع <number>.
  • callback من النوع <Function>.
  • القيمة المُعادة: <http.IncomingMessage>

تستدعي الدالة message.connection.setTimeout(msecs, callback)‎.

message.socket

أُضيفت مع الإصدار: v0.3.0.

كائن <net.Socket> المرتبط بالاتصال.

مع دعم HTTPS، تستخدم request.socket.getPeerCertificate()‎ للحصول على تفاصيل المصادقة الخاصة بالعميل.

message.statusCode

أُضيفت مع الإصدار: v0.1.1.

صالحة فقط للاستجابة المُعادة من http.ClientRequest.

رمز حالة استجابة HTTP المكون من 3 أرقام. على سبيل المثال 404.

message.statusMessage

أُضيفت مع الإصدار: v0.11.10.

صالحة فقط للاستجابة المُعادة من http.ClientRequest.

رسالة حالة استجابة HTTP (عبارة سببية). على سبيل المثال، OK أو Internal Server Error.

message.trailers

أُضيفت مع الإصدار: v0.3.0.

كائن ملحقات الطلب والرد. تُرسل فقط عند الحدث 'end'.

message.url

أُضيفت مع الإصدار: v0.1.90.

صالحة فقط للطلب المُعاد من http.Server.

طلب سلسلة العنوان URL النصية. وتحتوي فقط على عنوان URL الموجود في طلب HTTP الفعلي. إذا كان الطلب هو:

GET /status?name=ryan HTTP/1.1\r\n
Accept: text/plain\r\n
\r\n

حينئذ يكون request.url:

'/status?name=ryan'

تحليل عنوان url إلى أجزائه يمكن استخدام require('url').parse(request.url)‎. مثال على ذلك:

$ node
> require('url').parse('/status?name=ryan')
Url {
  protocol: null,
  slashes: null,
  auth: null,
  host: null,
  port: null,
  hostname: null,
  hash: null,
  search: '?name=ryan',
  query: 'name=ryan',
  pathname: '/status',
  path: '/status?name=ryan',
  href: '/status?name=ryan' }

http.METHODS

أُضيفت مع الإصدار: v0.11.8.

قائمة بدوال HTTP المُدعومة بواسطة المحلل.

http.STATUS_CODES

أُضيفت مع الإصدار: v0.1.22.

مجموعة من جميع رموز حالة استجابة HTTP القياسية، والوصف الموجز لكل منها. على سبيل المثال، http.STATUS_CODES[404] === 'Not Found'‎.

http.createServer([options][, requestListener])‎

سجل التغييرات

الإصدار التغييرات
v9.6.0 أصبح وسيط options مدعومًا الآن.
v0.1.13 أُضيف مع الإصدار: v0.1.13.
  • options من النوع <Object>.
    • IncomingMessage من النوع ‎:<http.IncomingMessage>‎ لتحديد صنف IncomingMessage المستخدم. مفيدة لتمديد IncomingMessage الأصلي. القيمة الإفتراضية: IncomingMessage.
    • ServerResponse من النوع ‎<http.ServerResponse>‎: لتحديد صنف ServerResponse المُستخدم. مفيدة لتمديد ServerResponse الأصلي. القيمة الإفتراضية: ServerResponse.
  • requestListener من النوع <Function>
  • القيمة المُعادة: <http.Server>

لعرض نسخة جديدة من http.Server.

تُعد requestListener دالة تُضاف تلقائيًا إلى حدث 'request'.

http.get(options[, callback])‎

سجل التغييرات

الإصدار التغييرات
v7.5.0 يمكن أن يكون المعامل options كائن عنوان URL WHATWG.
v0.3.6 أُضيف مع الإصدار: v0.3.6.
  • options من النوع ‎<Object> | <String> | <URL>‎ تقبل نفس options مثل http.request()‎، مع تعيين method دائمًا على GET. تُتجاهل الخصائص الموروثة من سلسلة prototype.
  • callback من النوع <Function>.
  • القيمة المُعادة: <http.ClientRequest>.

نظرًا لأن معظم الطلبات هي طلبات GET بدون متون، فإن Node.js يوفر هذه الدالة المناسبة. الاختلاف الوحيد بين هذه الدالة ودالة http.request()‎ هو أنها تضبط الدالة على GET وتستدعي req.end()‎ تلقائيًا. لاحظ أن دالة رد النداء يجب أن تهتم باستهلاك بيانات الاستجابة للأسباب المذكورة في قسم http.ClientRequest.

تُستدعى callback مع وسيط واحد يمثل نسخة من http.IncomingMessage.

أمثلة عن جلب JSON:

http.get('http://nodejs.org/dist/index.json', (res) => {
  const { statusCode } = res;
  const contentType = res.headers['content-type'];

  let error;
  if (statusCode !== 200) {
    error = new Error('Request Failed.\n' +
                      `Status Code: ${statusCode}`);
  } else if (!/^application\/json/.test(contentType)) {
    error = new Error('Invalid content-type.\n' +
                      `Expected application/json but received ${contentType}`);
  }
  if (error) {
    console.error(error.message);
    // استهلاك بيانات الاستجابة لتفريغ الذاكرة
    res.resume();
    return;
  }

  res.setEncoding('utf8');
  let rawData = '';
  res.on('data', (chunk) => { rawData += chunk; });
  res.on('end', () => {
    try {
      const parsedData = JSON.parse(rawData);
      console.log(parsedData);
    } catch (e) {
      console.error(e.message);
    }
  });
}).on('error', (e) => {
  console.error(`Got error: ${e.message}`);
});

http.globalAgent

أُضيفت مع الإصدار: v0.5.9.

  • <http.Agent>

المثيل العام للوكيل Agent الذي يُستخدم كإعداد افتراضي لجميع طلبات عميل HTTP.

http.request(options[, callback])‎

سجل التغييرات

الإصدار التغييرات
v7.5.0 يمكن أن يكون معامل options عبارة عن كائن URL WHATWG.
v0.3.6 أُضيف مع الإصدار: v0.3.6.
  • options من النوع ‎<Object> | <string> | <URL>‎.
    • protocol من النوع <string> وهو البروتوكول المراد استخدامه. القيمة الإفتراضية: 'http:‎'.
    • host من النوع <string> وهو اسم المجال أو عنوان IP الخاص بالخادم المُصدَر إليه الطلب. القيمة الإفتراضية: 'localhost'.
    • hostname من النوع <string> وهو اسم مستعار للمضيف host. لدعم url.parse()‎، يفضل استخدام hostname على host.
    • family من النوع <number> وهي عائلة عنوان IP لاستخدامها عند حل host و hostname. القيم الممكنة هي 4 أو 6. عندما يكون غير محدد، يستخدم كل من IP v4 و v6.
    • port من النوع <number> وهو منفذ الخادم البعيد. القيمة الإفتراضية: 80.
    • localAddress من النوع <string> وهو واجهة محلية لربط اتصالات الشبكة.
    • socketPath من النوع <string> وهو Unix Domain Socket (ويستخدم host:port أو socketPath).
    • method من النوع <string> وهي سلسلة نصية تحدد طريقة طلب HTTP. القيمة الإفتراضية: 'GET'.
    • path من النوع <string> وهو مسار الطلب. يجب تضمين سلسلة الاستعلام النصية إذا كانت موجودة. على سبيل المثال '‎/index.html?page=12'. يرمى استثناء عندما يحتوي مسار الطلب على أحرف غير صالحة. حاليًا، يُرفض المسافات فقط ولكن هذا قد يتغير في المستقبل. القيمة الافتراضية: '/'.
    • headers من النوع <Object> كائن يحتوي على ترويسات الطلبات.
    • auth من النوع <string> وهي المصادقة الأساسية بمعنى 'user:password' لحساب ترويسة المصادقة.
    • agent من النوع ‎<http.Agent> | <boolean>‎ وهو يتحكم في سلوك الوكيل Agent. القيم المُمكنة:
      • undefined (القيمة الافتراضية): استخدم http.globalAgent لهذا المضيف والمنفذ.
      • كائن Agent: استخدام Agent المُمرر بشكل صريح.
      • false: يتسبب في استخدام Agent جديد بقيم افتراضية.
    • createConnection من النوع <Function> وهي دالة تنتج مقبس ودفق لاستخدامهما عند عدم استخدام خيار agent. يمكن استخدام هذا لتجنب إنشاء فئة Agent مخصص فقط لتجاوز الدالة createConnection الافتراضية. راجع agent.createConnection()‎ لمزيد من التفاصيل. أي دفق مزدوج Duplex هو قيمة مُعادة صالحة.
    • timeout من النوع <number> وهو رقم يُحدد مهلة المقبس بالمللي ثانية. سيضبط هذا الخيار المهلة قبل توصيل المقبس.
    • setHost من النوع <boolean> وهو يستخدم لتحديد ما إذا كانت ترويسة المضيف Host ستُضاف تلقائيًا أم لا. القيمة الافتراضية true.
  • callback من النوع <Function>.
  • القيمة المُعادة: <http.ClientRequest>

يحافظ Node.js على عدة اتصالات لكل خادم لإجراء طلبات HTTP. تسمح هذه الدالة لإحداها بإصدار الطلبات بشفافية.

يمكن أن تكون options كائنًا أو سلسلة أو كائن URL. إذا كانت options سلسلة نصية، ستُحلل تلقائيًا بواسطة url.parse()‎. إذا كان كائن URL، فسيتحول تلقائيًا إلى كائن options عادي.

سيُضاف معامل callback الاختياري كمستمع لمرة واحدة للحدث 'response'.

وتُعيد الدالة http.request()‎ نسخة من الصنف http.ClientRequest. ويُعد المثيل ClientRequest دفقًا قابلًا للكتابة. في حالة الحاجة إلى تحميل ملف له طلب من النوع POST، يجب الكتابة إلى كائن ClientRequest.

أمثلة

const postData = querystring.stringify({
  'msg': 'مرحبًا أيها العالم!'
});

const options = {
  hostname: 'www.google.com',
  port: 80,
  path: '/upload',
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': Buffer.byteLength(postData)
  }
};

const req = http.request(options, (res) => {
  console.log(`STATUS: ${res.statusCode}`);
  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
  res.setEncoding('utf8');
  res.on('data', (chunk) => {
    console.log(`BODY: ${chunk}`);
  });
  res.on('end', () => {
    console.log('No more data in response.');
  });
});

req.on('error', (e) => {
  console.error(`problem with request: ${e.message}`);
});

// كتابة البيانات لطلب المتن
req.write(postData);
req.end();

لاحظ أنه في هذا المثال قد أُستُدعي req.end()‎. يجب دائمًا استدعاء req.end()‎ مع http.request()‎ للدلالة على نهاية الطلب - حتى إذا لم تكن هناك بيانات تُكتب إلى متن الطلب.

إذا صادف حدوث أي خطأ أثناء الطلب (سواء كان ذلك أثناء حل DNS، أو أخطاء في مستوى TCP، أو أخطاء تحليل HTTP الفعلية) يُطلَق حدث 'error' على كائن الطلب المُعاد. كما هو الحال مع جميع أحداث 'error'، إذا لم تُسجَّل أي مستمعات، فسيُطرح الخطأ.

هناك بعض الترويسات الخاصة التي يجب ملاحظتها.

  • سيؤدي إرسال 'Connection: keep-alive' إلى إخطار Node.js بأن الاتصال بالخادم يجب أن يستمر حتى الطلب التالي.
  • سيؤدي إرسال ترويسة 'Content-Length' إلى تعطيل الترميز الافتراضي المُجزَّأ.
  • سيؤدي إرسال ترويسة 'Expect' إلى إرسال ترويسات الطلبات على الفور. عادة، عند إرسال ‎'Expect: 100-continue'‎، يجب ضبط كل من المهلة ومستمع للحدث 'continue'. لمزيد من المعلومات، راجع RFC2616 القسم 8.2.3.
  • سيؤدي إرسال ترويسة المُصادقة إلى إلغاء استخدام خيار auth لحساب المصادقة الأساسية.

مثال باستخدام URL كخيار options:

const options = new URL('http://abc:xyz@example.com');

const req = http.request(options, (res) => {
  // ...
});

في طلب ناجح، ستُرسل الأحداث التالية بالترتيب التالي:

  • 'socket'
  • 'response'
    • 'data' أي عدد من المرات، على كائن res (لن يُطلَق الحدث 'data' على الإطلاق إذا كان متن الاستجابة فارغًا، على سبيل المثال، في معظم عمليات إعادة التوجيه).
    • 'end' على كائن res
  • 'close'

في حالة حدوث خطأ في الاتصال، ستُطلق الأحداث التالية:

  • 'socket'
  • 'error'
  • 'close'

إذا أستُدعيت الدالة req.abort()‎ قبل نجاح الاتصال، فستُطلق الأحداث التالية بالترتيب التالي:

  • 'socket'
  • (تُستدعى الدالة req.abort()‎ هنا)
  • 'abort'
  • 'close'
  • 'error' مع الخطأ مع رسالة 'Error: socket hang up' ورمز 'ECONNRESET'

إذا أستُدعيت الدالة req.abort()‎ بعد تلقي الاستجابة، فستُطلق الأحداث التالية بالترتيب التالي:

  • 'socket'
  • 'response'
    • 'data' أي عدد من المرات، على كائن res.
  • (تُستدعى req.abort()‎ هنا)
  • 'abort'
  • 'close'
    • 'aborted' على كائن res
    • 'end' على كائن res
    • 'close' على كائن res

لاحظ أن ضبط خيار timeout أو استخدام الدالة setTimeout()‎ لن يؤدي إلى إلغاء الطلب أو القيام بأي شيء بجانب إضافة حدث 'timeout'.

مصادر

صفحةHTTP ‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎‎ في توثيق Node.js الرسمي.