node
服务器端概念:
- 网站的组成:
- 客户端:用户界面,浏览器,运行着使用html、css、js编写的网站
- 服务端(服务器的压力远比客户端高,所以一般对服务器电脑的配置要求很高):接收请求,做出响应,处理业务逻辑和存储数据
- IP:是互联网中设备的唯一标识
- 域名:就是IP地址的别名,为了方便我们记忆
- 端口:可以理解成银行的柜台窗口编号,是我们服务器向外提供服务的口子,范围是0~65536,我们应用程序一般从3000起步
- URL:统一资源定位符,是标识互联网中的资源地址的编址方式
- 一个完整的URL包含:传输协议://IP或域名:端口/资源路径
- 一般网站应用的默认端口是:80,可以省略不写
- HTTP(Hyper Text Transfer Protocol):超文本传输协议,超文本就是用HTML写的文本
- 本机IP:127.0.0.1
- 本机域名:localhost
创建网站服务器:
// 引入系统模块http
const http = require('http')
// 创建网站服务实例
const app = http.createServer()
// 监听客户端请求,并做出响应
app.on('request', (req/* 请求对象 */, res/* 响应对象 */) => {
res.end('hey man....')
})
// 监听端口,启动服务,注意,没有这一步,服务不会启动
app.listen(3000)
console.log('网站启动成功')
补充说明:node也是有基于事件驱动特性的
http协议:
- HTTP:超文本传输协议,它基于客户端和服务端架构工作,是请求和响应的标准
- 报文:是HTTP请求和响应过程中传递的数据,分为请求报文(请求头)和响应报文(响应头),它遵守规定好的格式
- 请求方法:
- GET:用来告诉服务端,我这次请求主要目的是获取数据
- POST:用来告诉服务端,我这次请求主要目的是添加数据
- 在服务端中如何获取客户端的请求方法?:req.method
- form表单的两个重要属性(由于有默认跳转行为,用户体验较差,所以我们一般不用这个提交数据,等后面学习了ajax之后,可以在背后偷偷摸摸发送数据):
- method: 指定请求方法
- action:指定请求地址
- 获取请求地址中的资源路径:req.url(注意:这里获取的仅仅是资源路径,并不是完整的URL)
- 注意:请求时,如果没有带资源路径,如发送的是这个请求地址:
http://localhost:3000
,这时req.url
获取到的是/
- 获取请求报文:
req.headers
,就是一个对象,可以通过键值对的点语法或者中括号语法获取到键的值
- 注意:请求时,如果没有带资源路径,如发送的是这个请求地址:
- HTTP状态码(仅仅只是一个标识,是我们人为约定好的,浏览器内部也是遵守这种逻辑,并不能影响响应数据,只是用来告诉客户端对于本次请求,对应的响应状态):
- 200:请求成功
- 500:服务端错误
- 400:客户端错误
- 404:资源没有找到
- 设置HTTP状态码:res.writeHead(500)
- 响应内容类型(为了告诉浏览器,本次请求响应给你的数据格式,浏览器会根据这种格式去解析数据):
- text/plain:纯文本,默认
- text/html
- application/javascript
- application/json
- image/jpeg
- …
- 设置响应内容类型以及编码格式:
res.writeHead(200, { 'Content-Type': 'text/html;charset=utf8' })
补充说明(重点理解):服务端的程序是我们自己写的,客户端(浏览器)的程序是浏览器厂商的程序员写的(会自动读取服务端响应给客户端的信息,也就是响应头中的信息)
get请求参数:
- 传递参数的两种方式:get、post
- get参数放在请求地址中,形如:
http://localhost:3000/index?name=zs&age=18
- 借助系统模块url把req.url解析成对象:
url.parse(req.url, true)
- 第一个参数是字符串形式的url
- 第二个参数是指是否将查询参数转换成对象,默认false
- 获取查询参数和资源路径:
const { query, pathname } = url.parse(req.url, true)
post请求参数:
-
post请求参数是放在请求报文中
-
post参数理论上来讲是可以有无限多个的,所以服务器不是一次性接收的,防止卡顿,接收时需要使用
data
和end
事件- data事件:监听每一次的请求数据,当数据量过大时,会执行多次
- end事件:监听请求参数传递结束,当数据传递完成就会触发,只会执行一次
-
post参数默认的格式(x-www-form-urlencoded)实际上和get参数的格式是一样的,在浏览器控制台中看到的是对象是因为浏览器为了方便我们查看给我美化了
-
可以使用系统模块querystring把请求参数转换成对象
范例:
const querystring = require('querystring') app.on('request', (req, res) => { let data = '' req.on('data', (dataChunk/* 本次获取到的数据块,并不是一次性拿到的 */) => { data += dataChunk }) req.on('end', () => { console.log(data) // name=zs&age=18 const params = querystring.parse(data) // { name: 'zs', age: '18' } res.end('ok, receive successfull.') }) })
路由:是服务端逻辑,由服务端决定,实际上就是服务端定义的资源路径列表,定义了各个路由对应的资源
静态资源:就是可以直接响应给客户端的资源,一般不会有变化,比如:html/js/css/image,同一个路由,多次访问不会有变化
-
处理默认请求地址
/
:if (pathname === '/') { pahtname = '/default.html' }
-
注意:浏览器在解析html代码时,如果遇到外链资源(js/css/image),如:link、img、script标签,浏览器就会自动发送请求获取该资源,这时每个资源的类型都不一样,怎么保证响应内容类型是匹配的呢?就不能写死
text/html
了,需要借助第三方模块mime
的getType(filepath)
方法动态获取资源类型,通过:npm i mime
安装,通过:const mime = require('mime')
导入- 补充说明:为什么不设置,有些浏览器也能认识该资源?是因为这个浏览器内核比较高级,如果到lowb浏览器中访问就凉了,这都是网站的问题,我们让代码更健壮就需要解决这种隐患
动态资源:同样的请求地址,响应不同的资源,比如:http://localhost:3000/center?userId=1
、http://localhost:3000/center?userId=2
,同样的资源路径,响应的页面不同