Node.js是什么:
-
node.js不是一门语言
-
node.js不是框架和库
-
node.js是一个javascript运行环境
Node.js组成:
- ECMAscript
- API
- 文件读写
- 网络服务的构建
- 网络通信
- HTTP服务器
- …
Node.js特性:
-
事件驱动,
-
非阻塞IO模型(异步),
-
轻量和高效
参考:
-
Node官网:https://nodejs.org
-
JavaScript参考教程:http://javascript.ruanyifeng.com/
-
Node入门:http://www.nodebeginner.org/index-zh-cn.html
-
官方API文档:https://nodejs.org/dist/latest-v6.x/docs/api/
-
cnode社区:https://cnodejs.org
核心模块
-
node为JavaScript提供了很多服务器级别的API,这些API绝大多数被包装到了一个具名的核心模块中了。
-
例如:文件操作的
fs
核心模块,构建服务器的http
核心模块,path
路径操作模块,os
操作系统模块…
用法:
let fs=require('fs');
let http=require('http');
...
模块化:
-
node中一次只能执行一个文件用
require('要引入的文件/模块路径')
相对路径./
不能省略 例如:require(./d)
-
在node中没有全局作用域,只有模块作用域(文件),不能访问到其他模块作用域的成员,只在当前文件/模块中有效,外部访问不到
-
如何让模块之间访问到成员
-
后加载:
require.js
-
//使用require可以加载 exports.js文件 let expo = require('./exports.js'); //得到 my is exports.js // console.log(expo.hello); //调用属性 // console.log(expo.sum(10, 10)); //可以调用的到exports 的方法 20
-
-
先导出:
exports.js
-
exports默认是一个空对象,将需要导出的转为exports的属性或方法,调用加载的文件才能使用这些属性和方法
-
console.log('my is exports.js'); // 必须将要导出的变为exports 属性或方法 exports.hello = 'how a you'; // exports.sum = function(x, y) { return x + y; }
-
-
Web服务器开发:
-
ip地址和端口号
- IP地址用来定位计算机
- 端口号用来定位具体的应用程序
- 一切需要互联网通信的软件都会占用一个端口号
- 端口号的范围从 0-65536之间
- 在计算机中有一些默认的端口号,最好不要去使用
- 例如;http服务的80端口
- 使用一些简单好记的就可以了,如3000,5000…
- 可以同时开启多个服务,但要确保不同服务占的端口号不一样
fs模块
文件系统模块fs
:
fs.readFile:读取文件
fs.writeFile:写入文件
fs.appendFile:追加内容
fs是file-system的简写,就是文件系统的意思
node中如果想要操作文件,就必须引入fs这个文件模块
fs这个模块中,就提供了所有文件操作相关的API
//fs.readFile就是读取文件
// 1.使用require方法加载fs 核心模块
let fs = require('fs');
// 2.读取文件
// 第一个参数是读取的文件路径
// 第二个参数是一个回调函数
// 回调函数接收两个参数 error data
// 成功:data 是读取到的数据 ,error是null
// 失败:data 是undefined ,error是错误对象
fs.readFile('./hello.txt', function(error, data) {
//判断是否成功,成功为null不执行跳过,失败返回一个错误对象
//进入判断
if (error) {
console.log('文件读取失败');
return;
}
// console.log(data);
// 输出<Buffer e6 88 91 e6 98 af e6 96 87 e4 bb b6>
// 默认文件中存储的是二进制 转为16进制输出
// 可以通过toString()方法转化成字符
console.log(data.toString());
});
```
--使用fs.writeFile写入内容--
let fs=require('fs'); //引入fs模块
fs.writeFile('./hello.txt','我用fs.write写入的内容',function(error){
if(error){
console.log('写入失败');
retrun;
}
console.log('写入成功')
})
--使用fs.appentFile追加内容--
let fs=require('fs');
fs.appendFile('./hello.txt','这是我追加的内容',function()
{
if(error){
console.log('追加失败');
retrun;
}
console.log('追加成功')
})
http模块
服务器模块http
步骤:
-
1.加载http模块
let http=require(‘http’);
-
-
2.使用
http.createServer()
方法创建一个Web服务器并返回server实例-
let server=http.createServer();
-
-
3.注册
request
请求事件当客户端请求过来,就会触发服务器的request事件,然后执行回调函数
-
server.on('request',function(request,response){ console.log('收到客户端请求,路径为:'+request.url) //将中文的gbk编码,改为浏览器能解析的utf-8编码 解决文字乱码 固定写法 response.setHeader('Content-Type', 'text/plain; charset=utf-8'); //根据不同的请求发送不同的响应 let url=request.url; //判断 if(url === '/'){ response.end('index主页面') }else if(url ==='/login'){ response.end('login登录页面') }else if(url ==='/data'){ let datas=[{name:'张山',score:'99'},{name:'王五',score:'100'}, {name:'李四',score:'95'},{name:'刘二',score:'80'}]; response.end(JSON.stringify(datas)); }else{ response.end('404 Not Found') } })
-
Content-Type :http://tool.oschina.nte/commons
-
response.setHeader('Content-Type', 'text/plain; charset=utf-8');
转编码类型 gbk=>utf-8- text/plain 普通文本
- text/html html文件
-
-
4.绑定端口号,启动服务器
-
server.listen(3000,function(){ console.log('服务器请求成功') })
-
到浏览器输入:localhost:3000
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j2x34zvd-1598186521518)(C:\Users\饮酒\AppData\Roaming\Typora\typora-user-images\1587103391889.png)]
url模块
路径模块url
let url=require('url')
let obj=url.parse('http://www.baidu.com/?name=张&age=15',true)
obj结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ifQTBvUn-1598186521525)(C:\Users\饮酒\AppData\Roaming\Typora\typora-user-images\1587388265394.png)]
主要的属性:
url.parse(url,第二个参数为true)
query:值为?后的提交内容 加上true后会以对象类型显示
pathname:所输入的路径
Node 中的模板引擎
引入:let template=require('art-template')
数据:let comment = [{
uname: '张山',
textarea: '今天天气不错!',
dateTime: '2020-04-20'
}]
let tep = template.render(data.toString(), {
comment: comment
})
response.end(tep)
在服务器编程中通常将公共文件如public
:要引用的css js 图片...
放在同一个文件夹中,在服务器中src href
会触发请求 a链接点击触发 路径都以服务器请求路径为主
//访问其他静态资源文件
if (url.indexOf('/public/') === 0) { //如果路径包含/public/
// console.log(url)
// url === /public/css/index.css
fs.readFile('.' + url, function (err, data) {
if (err) {
response.end('404 Not Found')
return console.log('文件未找到...')
}
response.end(data)
})
客户端重定向:将会自动跳转到 /
界面
1.状态码302
statusCode
2.在响应头中通过Location
定向
setHeader
response.statusCode=302
response.setHeader('Location','/') //第二个参数是跳转的url
response.end()
第三方模块express
重点
- 使用前先下载
express
到项目文件夹
express方法
-
使用步骤
const express=require('express') //引入模块 const app=express() //创建express服务器 app.listen(3000,()=> console.log('服务器开启...')) app.get('/api/getbooks',(request,response)=>{ //get请求 }) app.post('/api/addbook',(request,response)=>{ //post请求 })
express方法():
-
请求
req.query //get请求(查询字符串) 会获取到get携带的参数 url中 ? 后的 例:http://localhost:3000/get?id=1&name=lis req.params //get请求url直接携带的动态参数 例:http://localhost:3000/:id req.body //获取post 请求的请求体 post请求体获取前要配置
-
响应
res.send(字符串或对象) //响应结果 res.json(对象) // 以json格式响应结果 res.sendFile(文件的绝对路径) //可以将文件读取,同时将结果响应 res.set({ }) //设置响应头 res.status( 状态码 ) //设置状态码
获取POST请求体:
-
post请求体有两种格式
-
查询字符串格式
- 对应的请求头:
Content-Type: application/x-www-form-urlencoded
- 对应的请求头:
-
FormData对象
-
对应的请求头:
Content-Type:multipart/form-data;--xxxxxx
-
-
-
当请求体为查询字符串:
配置post请求:固定写法 app.use(express.urlencoded({extended:false})) //其实就是一种中间件的写法 //实现原理: app.use((req, res, next) => { if (req.method === 'POST') { var str = ''; req.on('data', chunk => { str += chunk; }); req.on('end', () => { const querystring = require('querystring') req.body = querystring.parse(str); next(); }) } else { next(); } });
express中间件:
- 中间件(Middleware ),特指业务流程的中间处理环节。
- 中间件,是express最大的特色,也是最重要的一个设计
- 很多第三方模块,都可以当做express的中间件,配合express,开发更简单。
- 一个express应用,是由各种各样的中间件组合完成的
- 中间件,本质上就是一个函数
- 每个中间件函数,共享req对象、共享res对象
- js代码中,所有的req对象是一个对象;所有的res是一个对象
- 使用
app.use()
注册的中间件,GET和POST请求都可以触发
语法:
//基本参数:err , req , res , next
//err为错误对象 next为该的开关 不调用就不会向下执行其他
//常用写法:
app.use((req,res,next)=>{
//设置跨域
res.set({ 'Access-Control-Allow-Origin':'*' })
//只需在中间件中设置一次,就不要再设置了
next() //记得加next 让他向下执行
})
//也可以在其他请求上添加中间件(个数不限),这个中间件就不再是公有的了
app.get('/api/get',(req,res,next)=>{},... , (req,res)=>{
})
中间件接收POST请求体:
-
POST请求体的类型(Content-Type)
- application/x-www-form-urlencoded 比如:id=1&name=zs&age=20
- form-data 比如,提交的是FormData对象
- application/json 比如,提交的是 {“id”: 1, “name”: “zs”, “age”: 20}
- 其他…
-
服务器端接收不同类型的请求体,使用的方式是不同的
- urlencoded —>
app.use(express.urlencoded({extended: false}));
- application/json —>
app.use(express.json());
– 没有演示 - form-data —> 服务器端使用第三方模块处理(
multer
)
- urlencoded —>
第三方中间件,实现跨域资源共享
cors
第三方模块:
使用方法:
- 下载
npm i cors
const cors = require('cors');
加载模块app.use(cors( ))
--注册中间件即可
开放静态资源:
-
允许客户端访问XX文件里面的文件
app.use(express.static('文件名称')) //可以多次调用
路由:
-
路由就是之前的接口处理程序
模块化路由:
-
为了方便对路由进行模块化的管理,Express 不建议将路由直接挂载到 app.js 上,而是分流到单独的模块,如:登录注册验证放在一个模块
1.创建对应的模块
api.js
2.在模块js中
const express=require('express'); //创建路由对象 router const router=express.Router();
3.向路由对象上挂载具体的路由
//就是将app换成router router.get('/getbooks',(req,res)=>{}); router.post('/addbook',(req,res)=>{});
4.使用module.exports向外共享路由对象
module.exports=router; //导出路由对象
5,在app.js中
app.use('/api',require(./api.js)) //加载文件模块 使用时=> 以/api/开始的都会到api.js中找 //以此类推... app.use('/my',require(./my.js))
-