[Nodejs] node寫個helloworld


http 模塊 與 hello world

hello world

let http = require("http");

http
  .createServer((request, response) => {
    response.writeHead(200, { "Content-type": "text/html;charset=utf-8" });
    if (request.url !== "/favicon.ico") {
      response.write("<b>hello world</>");
      response.write("</br>");
      response.end("<i>你好,世界</i>");
    }
  })
  .listen(8888);

console.log("server running at http://127.0.0.1:8888/");

首先引入 http 模塊,然后調用 http 的 createServer 方法,創建一個服務器,最后調用 listen 監聽一個端口.createServer 的第一個參數是一個函數,函數中接收 request 和 response 作為兩個參數.
打開瀏覽器輸入http://127.0.0.1:8888/就可以看到hello world

http

要使用 HTTP 服務器和客戶端,必須 require('http').http 模塊主要用於搭建 HTTP 服務.

http.createServer()

createServer 直接 new 一個 http.Server 的實例,傳入回調函數,然后再返回新建的 http.Server 實例

listen(port, host)

http.Server 實例的方法,為 connections 啟動一個 server 監聽

request 對象

createServer 的文檔是 http.createServer([options][, requestlistener]),request 對象是 createServer 方法中回調函數的第一個參數,自帶一些屬性和方法來獲取客戶端的請求信息和讀取客戶端請求的數據

  • method: 客戶端請求方式
  • url: 請求的地址
  • headers: 客戶端發送的請求頭信息
  • httpVersion: HTTP 請求版本
  • trailers: 客戶端發送的 trailers 對象信息。只有 IncommingMessage 對象的 end 事件觸發后才能讀取到該信息。
  • socket: 服務器端監聽客戶端請求的 socket 對象。
  • data 事件: 當服務器接收到客戶端發送的請求數據時觸發 data 事件。
  • end 事件: 當客戶端發送給服務器數據執行完畢時觸發 end 事件。

request 對象全部的綁定屬性和方法,直接 console.log(request)

IncomingMessage {
  _readableState:
   ReadableState {
     objectMode: false,
     highWaterMark: 16384,
     buffer: BufferList { head: null, tail: null, length: 0 },
     length: 0,
     pipes: null,
     pipesCount: 0,
     flowing: null,
     ended: false,
     endEmitted: false,
     reading: false,
     sync: true,
     needReadable: false,
     emittedReadable: false,
     readableListening: false,
     resumeScheduled: false,
     paused: true,
     emitClose: true,
     destroyed: false,
     defaultEncoding: 'utf8',
     awaitDrain: 0,
     readingMore: true,
     decoder: null,
     encoding: null },
  readable: true,
  .......
      Timeout {
        _called: false,
        _idleTimeout: 120000,
        _idlePrev: [Timeout],
        _idleNext: [TimersList],
        _idleStart: 108,
        _onTimeout: [Function: bound ],
        _timerArgs: undefined,
        _repeat: null,
        _destroyed: false,
        [Symbol(unrefed)]: true,
        [Symbol(asyncId)]: 9,
        [Symbol(triggerId)]: 8 },
     [Symbol(kBytesRead)]: 0,
     [Symbol(kBytesWritten)]: 0 },
  _consuming: false,
  _dumped: false }

request.url 在請求的時候會額外請求一個/favicon.ico,一般框架體系都會對這個進行處理

response 對象

response 對象由 HTTP 服務器在內部創建,表示服務器端的 HTTP 回應。 它作為第二個參數傳給 'request' 事

  • writeHead: 用來寫入 HTTP 回應的頭信息
  • end: 寫入 HTTP 回應的具體內容
  • write: 這會發送一塊響應主體

http 的響應

  • setHeader(key, value):指定 HTTP 頭信息。
  • write(str):指定 HTTP 回應的內容。
  • end():發送 HTTP 回應。

處理 get 請求

get 參數在 request 的 url 屬性上,通過 url.parse 將 url 轉化為對象

http
  .createServer((request, response) => {
    let pathname = url.parse(request.url).pathname;
    if (pathname !== "/favicon.ico") {
      if(pathname==="/login"){
         response.writeHead(200, { "Content-type": "text/html;charset=utf-8" });
         response.write("我就是get");
         response.end();
      }
    }
  })
  .listen(8888, "localhost");

處理 post 請求

當客戶端采用 POST 方法發送數據時,服務器端可以對 data 和 end 兩個事件,設立監聽函數,data 事件會在數據接收過程中,每收到一段數據就觸發一次,接收到的數據被傳入回調函數。end 事件則是在所有數據接收完成后觸發

    "/login": (request, response) => {
      let totalData = "";
      request.on("data", data => {
        totalData += data;
      });

      request.on("end", () => {
        response.writeHead(200, { "Content-type": "text/html;charset=utf-8" });
        response.write(totalData); //username=liudehua&password=123456&remark=%E6%88%91%E6%98%AF%E5%88%98%E5%BE%B7%E5%8D%8E%2C%E6%88%91%E6%98%AF%E4%B8%80%E5%90%8D%E6%AD%8C%E6%89%8B
        response.end();
      });
    },

路由的簡單應用

let http = require("http");

http
  .createServer((request, response) => {
    if (request.url !== "/favicon.ico") {
      if (request.url === "/") {
        response.writeHead(200, { "Content-type": "text/html;charset=utf-8" });
        response.end("你好,世界");
      } else if (request.url === "/login") {
        response.writeHead(200, { "Content-type": "text/html;charset=utf-8" });
        createForm(response);
        response.end("登錄");
      } else if (request.url === "/register") {
        response.writeHead(200, { "Content-type": "text/html;charset=utf-8" });
        createForm(response);
        response.end("注冊");
      } else {
        response.writeHead(404, { "Content-Type": "text/plain;charset=utf-8" });
        response.end("404找不到相關文件");
      }
    }
  })
  .listen(8888);

console.log("server running at http://127.0.0.1:8888/");

function createForm(response) {
  response.write("用戶名:<input type='text' name='username'>");
  response.write("</br>");
  response.write("密碼:<input type='text' name='password'>");
  response.write("</br>");
}

路由就是根據不同的選擇執行不同的函數代碼

url.parse 方法

解析 URL 字符串並返回 URL 對象。如果 urlString 不是字符串,則拋出 TypeError。如果 auth 屬性存在但無法解碼,則拋出 URIError。

語法

url.parse(urlStr, [parseQueryString], [slashesDenoteHost])

參數

  • urlStr:要解析的 URL 字符串
  • parseQueryString:如果設為 true,則返回的 URL 對象的 query 屬性會是一個使用 querystring 模塊的 parse() 生成的對象。 如果設為 false,則 query 會是一個未解析未解碼的字符串。 默認為 false
  • slashesDenoteHost:如果設為 true,則 // 之后至下一個 / 之前的字符串會解析作為 host。 例如, //foo/bar 會解析為 {host: 'foo', pathname: '/bar'} 而不是 {pathname: '//foo/bar'}。 默認為 false。
Url {
  protocol: 'http:',
  slashes: true,
  auth: null,
  host: 'localhost:8888',
  port: '8888',
  hostname: 'localhost',
  hash: null,
  search: '?username=liudehua&password=123456',
  query: 'username=liudehua&password=123456',
  pathname: '/login',
  path: '/login?username=liudehua&password=123456',
  href:
   'http://localhost:8888/login?username=liudehua&password=123456' }

用處

//當路徑為http://127.0.0.1:8888/register
console.log(pathname);// /register
console.log(request.url);// /register

//當路徑為http://127.0.0.1:8888/register?username=liudehua&password=123456
console.log(pathname);// /register
console.log(request.url);// /register?username=liudehua&password=123456

路由匹配

let http = require("http");
let url = require("url");

http
  .createServer((request, response) => {
    let pathname = url.parse(request.url).pathname;
    if (pathname !== "/favicon.ico") {
      router(pathname)(request, response);
    }
  })
  .listen(8888, "localhost");

function router(path) {
  let router = {
    "/": (request, response) => {
      response.writeHead(200, { "Content-type": "text/html;charset=utf-8" });
      response.end("你好,世界");
    },
    "/login": (request, response) => {
      response.writeHead(200, { "Content-type": "text/html;charset=utf-8" });
      createForm(response);
      response.end("登錄");
    },
    "/register": (request, response) => {
      response.writeHead(200, { "Content-type": "text/html;charset=utf-8" });
      createForm(response);
      response.end("注冊");
    },
    "/404": (request, response) => {
      response.writeHead(404, { "Content-Type": "text/plain;charset=utf-8" });
      response.end("404找不到相關文件");
    }
  };

  !Object.keys(router).includes(path) && (path = "/404");

  return router[path];
}

function createForm(response) {
  response.write("用戶名:<input type='text' name='username'>");
  response.write("</br>");
  response.write("密碼:<input type='text' name='password'>");
  response.write("</br>");
}

之后分別輸入 localhost:8888,localhost:8888/haha,localhost:8888/login,localhost:8888/register

Docs

Node.js http 文檔
MDN HTTP
koajs
koa-docs-Zh-CN
Http 模塊
HTTP 消息頭(HTTP headers)-常用的 HTTP 請求頭與響應頭


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM