最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

NodeJS搭建HTTP服務器的實現(xiàn)步驟

 更新時間:2018年10月12日 10:12:18   作者:PandaShen  
NodeJS中用來創(chuàng)建服務的模塊是http核心模塊,本篇就來介紹關于使用http模塊搭建HTTP服務器和客戶端的方法,以及模塊的基本 API,非常具有實用價值,需要的朋友可以參考下

前言

在 NodeJS 中用來創(chuàng)建服務的模塊是 http 核心模塊,本篇就來介紹關于使用 http 模塊搭建 HTTP 服務器和客戶端的方法,以及模塊的基本 API。

HTTP 服務器

1、創(chuàng)建 HTTP 服務器

在 NodeJS 中,創(chuàng)建 HTTP 服務器可以與 net 模塊創(chuàng)建 TCP 服務器對比,創(chuàng)建服務器有也兩種方式。

方式 1:

const http = require("http");

const server = http.createServer(function(req, res) {
  // ......
});

server.listen(3000);

方式 2:

const http = require("http");

const server = http.createServer();

server.on("request", function(req, res) {
  // ......
});

server.listen(3000);

在 createServer 的回調和 request 事件的回調函數(shù)中有兩個參數(shù),req(請求)、res(響應),基于 socket,這兩個對象都是 Duplex 類型的可讀可寫流。

http 模塊是基于 net 模塊實現(xiàn)的,所以 net 模塊原有的事件在 http 中依然存在。

const http = require("http");

const server = http.createServer();

// net 模塊事件
server.on("connection", function(socket) {
  console.log("連接成功");
});

server.listen(3000);

2、獲取請求信息

在請求對象 req 中存在請求的方法、請求的 url(包含參數(shù),即查詢字符串)、當前的 HTTP 協(xié)議版本和請求頭等信息。

const http = require("http");

const server = http.createServer();

server.on("request", function(req, res) {
  console.log(req.method); // 獲取請求方法
  console.log(req.url); // 獲取請求路徑(包含查詢字符串)
  console.log(req.httpVersion); // 獲取 HTTP 協(xié)議版本
  console.log(req.headers); // 獲取請求頭(對象)

  // 獲取請求體的內容
  let arr = [];

  req.on("data", function(data) {
    arr.push(data);
  });

  req.on("end", function() {
    console.log(Buffer.concat(arr).toString());
  });
});

server.listen(3000, function() {
  console.log("server start 3000");
});

通過 req 對應的屬性可以拿到請求行和請求首部的信息,請求體內的內容通過流操作來獲取,其中 url 中存在多個有用的參數(shù),我們自己處理會很麻煩,可以通過 NodeJS 的核心模塊 url 進行解析。

const url = require("url");
let str = "http://user:pass@www.pandashen.com:8080/src/index.html?a=1&b=2#hash";

// parse 方法幫助我們解析 url 路徑
let obj = url.parse(str, true);

console.log(obj);

// {
//   protocol: 'http:',
//   slashes: true,
//   auth: 'user:pas',
//   host: 'www.pandashen.com:8080',
//   port: '8080',
//   hostname: 'www.pandashen.com',
//   hash: '#hash',
//   search: '?a=1&b=2',
//   query: '{ a: '1', b: '2' }',
//   pathname: '/src/index.html'
//   path: '/src/index.html?a=1&b=2',
//   href: 'http://user:pass@www.pandashen.com:8080/src/index.html?a=1&b=2#hash' }

在被解析路徑返回的對象中有幾個屬性被經常使用:

  • host:主機(域名 + 端口號);
  • hostname:主機名;
  • query:請求參數(shù)(查詢字符串或參數(shù)對象);
  • pathname:資源路徑(根據(jù)不同的路徑返回不同的資源)。

我們使用 url 的 parse 方法來幫我們解析請求路徑,在真實的服務器中傳入的第一個參數(shù)為 req.url,第二個參數(shù)不傳時,query 會被解析成 a=1&b=2 的形式,第二個參數(shù)傳入 true,query 屬性的查詢字符串會被解析成對象的形式。

url 模塊中,將查詢字符串 a=1&b=2 轉換為對象 { a: '1', b: '2' } 的實現(xiàn)方式其實是使用正則替換實現(xiàn)的。

模擬查詢字符串轉換對象的核心邏輯:

let str = "a=1&b=2&c=3";
let obj = {};

str.replace(/([^=&]+)=([^=&]+)/g, function() {
  obj[arguments[1]] = arguments[2];
});

console.log(obj); // { a: '1', b: '2', c: '3' }

在上面代碼的 replace 方法的回調函數(shù)中參數(shù)集合的第一項為匹配到的字符串,第二項為第一個分組的值,第三項為第二個分組的值,依次類推,倒數(shù)第二項為分組匹配的索引,最后一項為原字符串。

3、設置響應信息

我們可以通過 req 來獲取請求信息,自然也可以通過 res 來設置響應信息返回給客戶端。

const http = require("http");

const server = http.createServer();

server.on("request", function(req, res) {
  // 設置響應頭(過去的用法),不能多次調用,見到要認識
  res.writeHead(200, { "Content-Type": "text", a: "hello world" });

  // 設置響應頭(現(xiàn)在的用法,常用),可以多次調用,每次設置一個響應頭
  res.setHeader("Content-Type", "text");

  // 設置狀態(tài)碼,不設置默認為 200
  res.statusCode = 200;

  // 不發(fā)送 Date(日期)響應頭
  res.sendDate = false;

  // 返回內容
  res.write("hello world"); // 不會關閉連接
  res.end("hello world"); // 將內容返回后關閉連接
});

server.listen(3000, function() {
  console.log("server start 3000");
});

返回給客戶端的信息主要分為兩部分,分別為響應頭和返回給瀏覽器的內容,在不設置響應頭的情況下,默認會設置響應頭 Content-Length 和 Date ,代表當前返回給客戶端的內容長度和日期。

返回給瀏覽器的內容可以通過 res 的 write 方法和 end 方法進行發(fā)送,write 方法不會斷開連接(通常在響應后需要斷開與客戶端的連接),end 方法會斷開連接,在 end 方法存在參數(shù)時,會在內部調用 write 將參數(shù)內容返回給客戶端,并斷開連接。

HTTP 客戶端

在 net 模塊中可以通過 net.createConnection 來創(chuàng)建客戶端,并發(fā)送請求到服務端,在 http 模塊同樣可以創(chuàng)建客戶端,并向 http 服務器發(fā)送請求。

// 客戶端:client.js
const http = require("http");

// 發(fā)送請求的配置
let config = {
  host: "localhost",
  port: 3000,
  method: "get",
  headers: {
    a: 1
  }
};

// 創(chuàng)建客戶端
let client = http.request(config, function(res) {
  // 接收服務端返回的數(shù)據(jù)
  let arr = [];

  res.on("data", function(data) {
    arr.push(data);
  });

  res.on("end", function() {
    console.log(Buffer.concat(arr).toString());
  });
});

// 發(fā)送請求
client.end();

在 http 模塊中通過 request 方法創(chuàng)建客戶端,該方法第一個參數(shù)為發(fā)送請求的配置,包含請求地址、端口號、請求方法以及請求頭等,第二個參數(shù)為回調函數(shù),在請求被響應后執(zhí)行,回調函數(shù)的參數(shù)為服務器的響應對象 res,創(chuàng)建的客戶端通過 end 方法將請求發(fā)出與服務端進行通信。

使用 NodeJS 實現(xiàn)的 “爬蟲” 其實就可以通過 http 模塊創(chuàng)建的客戶端來實現(xiàn),客戶端幫我們向我們要抓取數(shù)據(jù)的地址發(fā)送請求,并拿到響應的數(shù)據(jù)進行解析。

同時使用 HTTP 客戶端和服務器

我們使用自己創(chuàng)建的客戶端訪問自己的服務端,并體會請求響應的過程,就是用上面 client.js 作為客戶端,啟動 server.js 后再啟動 client.js 查看效果。

// 服務器:server.js
const http = require("http");

http.createServer(function(req, res) {
  console.log("The request came");

  // 獲取客戶端請求信息
  console.log(req.method);
  console.log(req.headers);

  // 返回數(shù)據(jù)
  res.write("hello world");
}).listen(3000, function() {
  console.log("server start 3000");
});

簡易爬蟲

我們結合 http 模塊創(chuàng)建的服務端和客戶端實現(xiàn)一個簡易版的 “爬蟲” 去抓取百度新聞頁所有 li 標簽內的文章標題。

// 簡易爬蟲:crawl.js
const http = require("http");

// 創(chuàng)建服務器
const server = http.createServer();

// 監(jiān)聽請求
server.on("request", function(req, res) {
  let client = http.request(
    {
      host: "news.baidu.com",
      method: "get",
      port: 80
    },
    function(r) {
      // 接收百度新聞返回的數(shù)據(jù)
      let arr = [];

      r.on("data", function(data) {
        arr.push(data);
      });

      r.on("end", function() {
        // 處理數(shù)據(jù)
        let result = Buffer.concat(arr).toString();
        let matches = result.match(/<li class="bold-item">([\s\S*?])<\/li>/gm);

        // 設置返回給瀏覽器的文檔類型和編碼格式
        res.setHeader("Content-Type", "text/html;charset=utf8");

        // 響應瀏覽器
        res.end(matches.join(""));
      });
    }
  );

  client.end();
});

server.listen(3000);

上面的正則匹配中 ([\s\S*?]) 代表匹配 <li class="bold-item"> 到 <\/li> 之間所有內容(多個字符、非貪婪模式),gm 代表全局并多行匹配。

上面爬取百度新聞數(shù)據(jù)的過程中,我們自己的 Node 服務器扮演了一個 “中間層” 的角色,我們通過瀏覽器訪問自己的服務器 localhost:3000 觸發(fā) request 事件,執(zhí)行了回調,在回調中創(chuàng)建客戶端向 news.baidu.com 發(fā)送了請求,并在客戶端的回調中處理了響應(百度新聞頁返回的數(shù)據(jù)),將處理后的內容通過我們自己 Node 服務器的 res 對象返回給了瀏覽器。

總結

相信在讀過本篇文章之后對搭建一個 Node 服務應該已經有了思路,為未來通過 Node 服務實現(xiàn)復雜的業(yè)務場景及數(shù)據(jù)的處理打下了一個基礎,希望初學 Node 的小伙伴在看了這篇文章后能有所收獲。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Node.js使用Express.Router的方法

    Node.js使用Express.Router的方法

    這篇文章主要為大家詳細介紹了Node.js使用Express.Router的方法 ,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Node.js(安裝,啟動,測試)

    Node.js(安裝,啟動,測試)

    這里主要介紹基于windows平臺上最簡單方便的安裝方式,啟動以及簡單測試
    2014-06-06
  • 在Node.js中實現(xiàn)關注列表和粉絲列表的方法示例

    在Node.js中實現(xiàn)關注列表和粉絲列表的方法示例

    在社交網絡或者任何需要用戶交互的應用中,實現(xiàn)關注和被關注的功能是非常常見的需求,本文將通過一個簡單的例子,展示如何在Node.js環(huán)境下實現(xiàn)用戶的關注列表和粉絲列表,需要的朋友可以參考下
    2024-04-04
  • Node.js中module.exports?和exports使用誤區(qū)

    Node.js中module.exports?和exports使用誤區(qū)

    本文主要介紹了Node.js中module.exports?和exports使用誤區(qū),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • node.js學習之base64編碼解碼

    node.js學習之base64編碼解碼

    開發(fā)者對Base64編碼肯定很熟悉,是否對它有很清晰的認識就不一定了。實際上Base64已經簡單到不能再簡單了,這篇文章給大家通過示例代碼介紹了node.js對字符串和圖片base64編碼解碼的方法,有需要的朋友們可以通過本文來進行學習,下面來一起看看吧。
    2016-10-10
  • nodejs前端模板引擎swig入門詳解

    nodejs前端模板引擎swig入門詳解

    這篇文章主要介紹了nodejs前端模板引擎swig入門詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • node 使用 async 控制并發(fā)的方法

    node 使用 async 控制并發(fā)的方法

    這篇文章主要介紹了node 使用 async 控制并發(fā)的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • Node.js刷新session過期時間的實現(xiàn)方法推薦

    Node.js刷新session過期時間的實現(xiàn)方法推薦

    下面小編就為大家?guī)硪黄狽ode.js刷新session過期時間的實現(xiàn)方法推薦。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-05-05
  • Nodejs libuv運行原理詳解

    Nodejs libuv運行原理詳解

    在本篇文章里小編給大家整理的是關于Nodejs libuv運行原理以及相關知識點,有需要的朋友們可以學習下。
    2019-08-08
  • 使用pify實現(xiàn)Node.js回調函數(shù)的Promise化

    使用pify實現(xiàn)Node.js回調函數(shù)的Promise化

    使用pify庫,你可以非常便利地將任何遵循Node.js回調風格的函數(shù)轉換為返回Promise對象的函數(shù),從而使得你的異步代碼更加清晰和易于維護,本文通過豐富的代碼示例引導你如何有效地利用pify,需要的朋友可以參考下
    2024-06-06

最新評論

浙江省| 睢宁县| 平塘县| 收藏| 苏尼特右旗| 旬阳县| 林州市| 林州市| 旬阳县| 库车县| 钟祥市| 台东市| 上高县| 南木林县| 玉门市| 宜黄县| 桃源县| 邯郸县| 砚山县| 延长县| 容城县| 祁连县| 奎屯市| 榆林市| 温泉县| 虞城县| 安国市| 白银市| 交城县| 通渭县| 合山市| 通许县| 垫江县| 横山县| 广平县| 乐平市| 高密市| 云阳县| 元阳县| 双鸭山市| 宜宾市|