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 请求头与响应头

[Nodejs] node写个hello,world的更多相关文章

  1. 初步学习nodejs,业余用node写个一个自动创建目录和文件的小脚本,希望对需要的人有所帮助

    初步学习nodejs,业余用node写个一个自动创建目录和文件的小脚本,希望对需要的人有所帮助,如果有bug或者更好的优化方案,也请批评与指正,谢谢,代码如下: var fs = require('f ...

  2. nodejs,node原生服务器搭建实例

    nodejs,node原生服务器搭建实例

  3. [Nodejs] 用node写个爬虫

    寻找爬取的目标 首先我们需要一个坚定的目标,于是找个一个比较好看一些网站,将一些信息统计一下,比如 url/tag/title/number...等信息 init(1, 2); //设置页数,现在是1 ...

  4. nodejs初写心得

    nodejs安装后如何查看和安装其他工具 网上nodejs的文章已经很多,这里只是写下自己的小小心得,如果能帮到别人当然更好. 安装nodejs这里就不叙述了,直接上nodejs官网下载就好了,初学者 ...

  5. 用node写一个皖水公寓自动刷房源脚本

    因为住的地方离公司太远,每天上下班都要坐很久的班车,所以最近想搬到公司旁边的皖水公寓住.去问了一下公寓的客服,客服说房源现在没有了,只能等到别人退房,才能在网站上申请到. 如果纯靠手动F5刷新浏览器, ...

  6. [Nodejs] node实现静态文件服务器

    node 静态文件处理 一般后端进行静态文件处理都是使用 Apache nginx 等静态 web 服务器,但是既然使用 node 了,就用 node 实现以下静态服务器吧. 之前弄了不少充满艺术的数 ...

  7. [Nodejs] node的fs模块

    fs 模块 Node.js 提供一组类似 UNIX(POSIX)标准的文件操作 API. Node 导入文件系统模块(fs).Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如 ...

  8. [NodeJS] Node.js 与 V8 的故事

    要说Node.js的历史,就不得不说说V8历史.在此之前我们先一句话描述一下什么是Node.js:Node.js是一个基于Google Chrome V8 Javascript引擎之上的平台,用以创建 ...

  9. node 写api几个简单的问题

    最近出了一直在做无聊的管理后台,还抽空做了我公司的计费终端,前端vue,后端node,代码层面没啥太多的东西.由于自己node版本是8.0.0,node自身是不支持import和export的,要想基 ...

随机推荐

  1. COGS2421 [HZOI 2016]简单的Treap

    题面见这里 大概是个模板题 Treap暴力插入的做法太暴力了并不优美 这里就需要用到笛卡尔树的构造方法,定义见这里 在 假的O(n) 的时间内构造一棵Treap 把元素从小到大排序 这样从小到大插入时 ...

  2. react-navigation android 导航标题居中

    先贴下代码供参考: 安卓默认导航的titile 是在左侧的,为了和iOS保持一致,需要添加 alignSelf:'center',这个 属性 但是会遇到title有点偏右的情况 添加headerRig ...

  3. 抽象工厂模式--java代码实现

    抽象工厂模式 抽象工厂模式,对方法工厂模式进行抽象.世界各地都有自己的水果园,我们将这些水果园抽象为一个水果园接口,在中国.英国和美国都有水果园,种植不同的水果,比如苹果.香蕉和梨等.这里将苹果进行抽 ...

  4. [Hyperledger] Fabric系统中 peer模块的 gossip服务详解

    最近一直在看fabric系统中的核心模块之一——peer模块.在看peer的配置文件core.yaml的信息时,对其中的gossip配置选项很感兴趣.看了一上午,还是不能明白这个选项到底什么意思呢?表 ...

  5. Hive使用必知必会系列

    一.Hive的几种数据模型 内部表 (Table 将数据保存到Hive 自己的数据仓库目录中:/usr/hive/warehouse) 外部表 (External Table 相对于内部表,数据不在自 ...

  6. Asp.Net Core 轻松学-经常使用异步的你,可能需要看看这个文章

    前言 事情的起因是由于一段简单的数据库连接代码引起,这段代码从语法上看,是没有任何问题:但是就是莫名其妙的报错了,这段代码极其简单,就是打开数据库连接,读取一条记录,然后立即更新到数据库中.但是,惨痛 ...

  7. Git常用命令拾遗

    git三个区 下图是git的提交流程,是入门或者说是理解git的重要图谱. 我们可以看到这里有三个区:工作区.暂存区.提交区.截止到commit阶段,其实都只是在本地离线操作,真正同步到中心服务器,需 ...

  8. Quartz.Net学习笔记

    一.概述 Quartz.NET是一个强大.开源.轻量的作业调度框架,是 OpenSymphony 的 Quartz API 的.NET移植,用C#改写,可用于winform和asp.net应用中.它灵 ...

  9. Java多线程与并发之面试常问题

    JAVA多线程与并发 进程与线程的区别 进程是资源分配的最小单位,线程是CPU调度的最小单位 所有与进程相关的资源,都被记录在PCB(进程控制块)中 进程是抢占处理机的调度单位:线程属于某个进程,共享 ...

  10. box-decoration-break属性

    box-decoration-break属性可以指定元素片段在跨行.跨列或跨页(如打印)时候的样式渲染表现.默认情况下,元素的跨行或跨列渲染都是裁剪分割,各得一部分.举个例子<div class ...