一、Node.js是什么
是javascript运行时环境,简单来说,Node.js可以解析和执行javascript代码。以前只有浏览器解析和执行javascript代码,现在javascript可以完全脱离浏览器来运行,这一切都归功于Node.js。
浏览器中的javascript和node.js之间的区别:
浏览器中js包含EcmaScript、Dom、Bom,
Node.js中的javascript没有Bom和Dom,因为不操作页面,只有EcmaScript来操作服务器。在Nodejs这个Javascript执行环境中为js提供了一些服务器级别的API操作,包括文件读写、网络服务构建,网络通信,http服务器等处理。
EcmaScript包含:变量、方法、数据类型、内置对象(Array、Object、Date、Math)
Node特性
事件驱动
非阻塞IO模型(异步)
轻量和高效
原因:node构建于chrom的V8引擎之上,代码只具有特定格式的字符串而已,Nodejs的作者把Google chrome 中的V8引擎移出来,开发一个独立的javascript运行时环境。
Node能做什么
Web服务器后台
命令行工具:npm、git、hexo等
二、Node的使用
执行js脚本文件命令
node js文件.js
读取文件
var fs=require('fs');
fs.readFile('./data/hello.txt',function(error,data){
if(error){
console.log('读取失败')
}
else{
console.log(data.toString())
}
})
注:文件中存储的其实都是二进制数据 0 1
// 这里为什么看到的不是 0 和 1 呢?原因是二进制转为 16 进制了
// 但是无论是二进制01还是16进制,人类都不认识
// 所以我们可以通过 toString 方法把其转为我们能认识的字符
写文件
var fs = require('fs');
fs.writeFile('./data/hello.txt','大家好,我xxxx',function(error){
if(error){
console.log('写入失败')
}
else{
console.log('写入成功')
}
})`
文件写入成功,error就是null,失败error就是错误对象,data失败就是undefined,没有数据,没有tostring属性
创建服务器
http模块的指责就是帮助创建编写服务器,请求发过来,触发request请求事件
var http = require('http');
var server = http.createServer();
server.on('request',function(request,response){console.log('收到客户端的请求了,请求路径 是:'+request.url)
response.end('hello world')
});
server.listen(3000,function(){})
注:请求路径前面带/
例如 http://127.0.0.1:3000/ 为 /
http://127.0.0.1:3000/a 为 /a http://127.0.0.1:3000/foo/b 为 /foo/b
response 对象有一个方法:write 可以用来给客户端发送响应数据
write 可以使用多次,但是最后一定要使用 end 来结束响应,否则客户端会一直等待response.write(‘hello’)
response.end()
方法几乎不用
用
response.end('hello world')
代替根据不同的请求路径返回不同的数据
1、获取请求路径
req.url获取的是端口号之后的,带/
响应的类型必须是字符串
1
2
3
4
5
6
7
8
9 >server.on('request',function(req,res){
> var url = req.url
> if(url=='/'){
> res.end('index page')
> }else{
> res.end('404')
> }
> });
>
Node的模块化
Node为javaScript提供了很多服务器级别的API,这些API绝大多数都被包装到了一个具名的核心模块中 了,例如文件操作模块fs
核心模块,http< 大专栏 nodejs学习笔记|undefined/code>服务构建的模块、
path
路径操作模块、os操作系统信息模块
模块有两种:
具名的核心模块:fs、http等
用户自己编写的文件模块
require加载方法:
require(‘fs’)加载核心模块
require(./a.js)加载用户自己编写的文件,.js可以省略,推荐使用require(./a)
require方法有两个作用:
加载文件模块并执行里面的代码
拿到加载的文件模块导出接口对象
例如b.js文件:exports.foo = 'hello'
exports.add= function(x,y){
return x+y
}
变量foo和add函数挂载到exports接口对象中后,可以被外部加载访问
外部模块拿到b.js模块导出的接口对象bExports
var bExports = require('./b')
var s = bExports.add(10,30)
模块化的好处
可以加载执行多个文件
外部访问不到内部,内部访问不到内部,可以完全避免变量命名冲突污染的问题
四、http服务器开发
#####用户输入的网址通过DNS解析ip地址
#####IP地址和端口号分别是用来定位计算机和应用程序的
一切需要联网通信的软件都会占用一个端口号
端口号的范围是0-65536之间
在计算机中有一些默认的端口号,最好不要去使用,例如http服务的80端口
可以同时开启多个服务,但一定要确保不同的服务占用的端口号不一致才可以,在一台计算机中,同一个端口号同一时间只能被一个程序使用
#####乱码问题
服务端默认发送的数据是UTF-8编码的,但浏览器不知道,所以浏览器会按照当前操作系统的默认编码解析,所以浏览器显示会出现乱码
解决办法:告诉浏览器发送的内容是以utf-8编码的
res.setHeader(‘content-Type’,’text/plain;charset=utf-8’)
#####服务器应该每次把相应的数据内容类型告诉客户端
http
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
var fs = require('fs')
var server = http.createServer()
server.on('request', function (req, res) {
var url = req.url
if (url === '/') {
// 肯定不这么干
// res.end('<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"> <title>Document</title></head><body><h1>首页</h1></body>/html>')
// 我们要发送的还是在文件中的内容
fs.readFile('./resource/index.html', function (err, data) {
if (err) {
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
res.end('文件读取失败,请稍后重试!')
} else {
// data 默认是二进制数据,可以通过 .toString 转为咱们能识别的字符串
// res.end() 支持两种数据类型,一种是二进制,一种是字符串
res.setHeader('Content-Type', 'text/html; charset=utf-8')
res.end(data)
}
})
} else if (url === '/xiaoming') {
// url:统一资源定位符
// 一个 url 最终其实是要对应到一个资源的
fs.readFile('./resource/ab2.jpg', function (err, data) {
if (err) {
res.setHeader('Content-Type', 'text/plain; charset=utf-8')
res.end('文件读取失败,请稍后重试!')
} else {
// data 默认是二进制数据,可以通过 .toString 转为咱们能识别的字符串
// res.end() 支持两种数据类型,一种是二进制,一种是字符串
// 图片就不需要指定编码了,因为我们常说的编码一般指的是:字符编码
res.setHeader('Content-Type', 'image/jpeg')
res.end(data)
}
})
}
})
server.listen(3000, function () {
console.log('Server is running...')
})