Node.js

1.作用:

  • 用来创建web服务器

2.创建web服务器的步骤:

  • 导入http模块

  • 创建一个web服务器的实例

  • 监听客户端的请求

  • 启动服务

3.req对象和res对象:

  • req请求对象,包含请求相关信息(请求方式,请求地址等)

  • res响应对象,包含响应相关信息:res.end(响应的内容);

4.解决响应中文乱码的问题:

  • 设置响应头: res.setHeader('Content-Type', 'text/html; charset=utf-8')

5.Node中模块化:

  1. 模块化概念:将一个文件拆分成多个独立并且相互依赖的小模块

  2. 好处:①提高代码的复用性;②提高代码的可维护性;③可以实现按需加载

  3. 模块化分类:①内置模块:Node.js官方提高;②自定义模块:用户创建的每个js文件就是一个模块;③第三方模块:第三方开发的模块,下载安装之后才能使用

6.模块的加载(★★★★★):

  • 使用require()方法加载需要的内置模块、用户自定义模块、第三方模块进行使用

  • 使用require()方法加载其他模块时,会执行被加载模块中的代码

  • 在使用require()加载用户自定义模块期间,可以省略.js后缀名

  • 使用 require() 方法导入模块时,导入的结果,永远以module.exports 指向的对象为准

7.对外共享模块成员:

  1. 给module.exports对象上面挂载属性

  2. 让module.exports指向一个形象

  3. 给exports对象上面挂载属性

二、包(★★★★★):

1.使用步骤:

1.使用npm安装包
2.导入包
3.根据使用包的文档进行书写

2.npm包管理器:

1.安装包:npm i 包的名称或者是npm install 包的名称
2.卸载包:npm uninstall 包的名称
3.指定包的版本: npm i 包的名称@版本

3.包配置管理:

  1. 快速创建package.json命令(node init -y);

注意:只能在英文的目录下成功运行,目录不要出现中文,空格

  1. dependencies节点:运行命令: npm i 包的名称。用来记录项目开发和上线需要用到的包

  2. devDependencies 节点

三、express框架

1.创建web服务器:

//导入包
const express  = require('express')
//创建服务器
const app = express()
//启动服务器
app.listen('3000',()=>{
    console.log('http://localhost:3000')
})

2.监听get和set请求:

  • app.get(请求的url地址,请求对应的处理函数)

  • app.post(请求的url地址,请求对应的处理函数)

3.获取查询参数:

  • req.query,获取到的是对象

4.获取动态参数:

  • req.params ,获取到的是对象

5.托管静态资源:

  1. app.use(express.static(指定的静态目录))

  2. 挂载路径前缀:app.use('/前缀名',express.static(指定的静态目录))

  3. 访问静态资源文件时,express.static()函数会根据目录的加载顺序查找所需的文件

四、express路由:

1.概念

  • 客户端请求和服务器处理函数之间的映射关系

2.定义路由的语法:

  1. app.get(url地址,请求处理函数)

  2. app.post(url地址,请求处理函数)

3.路由的匹配:

  • 按照定义的先后顺序进行匹配,请求类型和请求的URL同时匹配成功,才会调用对应的处理函数

4.路由模块化

4.1.定义路由:

//引入express
const express = require('express')
//创建路由
const router = express.Router()
//挂载路由
router.get("/api/getbooks", (req, res) => {
  res.send("/api/getbooks被监听到了");
});
router.post("/addbooks",(req,res)=>{
  res.send({
    status:201,
    message:"添加图书成功"
  })
})
//导出路由
module.exports = router

4.2注册路由:

//导入路由
const router = reqiure('./3-router')
//注册路由
app.use('/api',router)

五、express中间件:

1、概念:

  • 业务流程的中间处理环节,是对请求的预处理

2、中间件语法格式:

//定义中间件
const kw = function(req,res,next){
    console.log('中间件被触发了')
    //一定要加,否则就无法执行下面的路由
    next()
}

3、全局中间件

const express = require("express");
const app = express();
/**
 * 中间件:
 *   概念:业务的中间处理环节,,做请求的预处理
 *   语法:(req,res,next)=>{next()}
 *   位置:路由在路由之前定义并且注册中间件
 *   注意:
 *     一定要在中间件调用next(),进行流转关系的转移
 *     如果不写,请求处理了,不会有响应
 */
// 定义中间件
// const kw = (req, res, next) => {
//   console.log("我是中间件");
//   //一定要在中间件调用next()
//   next();
// };
// // 注册中间件
// app.use(kw);
​
// 简写方式
// 全局中间件(就是每一个路由,都要经过这个中间件)
app.use((req, res, next) => {
  console.log("我是中间件1");
  next();
});
app.use((req, res, next) => {
  console.log("我是中间件2");
  next();
});
​
// 挂载路由
app.get("/api/getbooks", (req, res) => {
  res.send("获取图书成功");
});
app.post("/api/addbook", (req, res, next) => {
  res.send("添加图书成功");
});
​
app.listen(3000, () => {
  console.log("http://localhost:3000");
});
​

3.1注意点:每个请求都会经过这个中间件

4、局部中间件:

4.1、注意点:

  • 一定要执行在路由之前,注册中间件

  • 客户端发送过来的请求,可以连续调用多个中间件进行处理

  • 执行完中间件的业务代码之后,不要忘记调用next()函数

  • 为了防止代码逻辑混乱,调用next()函数后不要再写额外的代码

  • 连续调用多个中间件时,多个中间之间,共享req和res对象

  • 只有某个请求才会经过的中间件,定义在;路由处理函数的前面

4.2、完整代码:

const express = require("express");
const app = express();
/***
 * 中间件的的分类:
 *   全局中间件:每一个情求,都会经过这个全局的中间件
 *   局部中间件:只有某个请求,才会经过中间件
 */
// 定义中间件
// 局部中间件(只有某个路由,才经过这个中间件)
const kw = (req, res, next) => {
  console.log("我是中间件");
  next();
};
const kw1 = (req, res, next) => {
    console.log("我是中间件");
    next();
  };
// 挂载路由
app.get("/api/getbooks", [kw,kw1],(req, res) => {
  res.send("获取图书成功");
});
app.post("/api/addbook", (req, res, next) => {
  res.send("添加图书成功");
});
​
app.listen(3000, () => {
  console.log("http://localhost:3000");
});

5、中间件分类

5.1、应用级别的中间件:

  • 绑到app实例上的中间件

  • 完整代码:

    const express = require("express");
    const app = express();
    /**
     * 中间件:
     *   概念:业务的中间处理环节,,做请求的预处理
     *   语法:(req,res,next)=>{next()}
     *   位置:路由在路由之前定义并且注册中间件
     *   注意:
     *     一定要在中间件调用next(),进行流转关系的转移
     *     如果不写,请求处理了,不会有响应
     */
    // 定义中间件
    // const kw = (req, res, next) => {
    //   console.log("我是中间件");
    //   //一定要在中间件调用next()
    //   next();
    // };
    // // 注册中间件
    // app.use(kw);
    ​
    // 简写方式
    // 全局中间件(就是每一个路由,都要经过这个中间件)
    app.use((req, res, next) => {
      console.log("我是中间件1");
      next();
    });
    app.use((req, res, next) => {
      console.log("我是中间件2");
      next();
    });
    ​
    // 挂载路由
    app.get("/api/getbooks", (req, res) => {
      res.send("获取图书成功");
    });
    app.post("/api/addbook", (req, res, next) => {
      res.send("添加图书成功");
    });
    ​
    app.listen(3000, () => {
      console.log("http://localhost:3000");
    });

5.2、路由级别的中间件:

  • 绑定到router实例上的中间件

5.3、错误级别的中间件:

  • 作用:用来捕获整个项目中发生的异常错误,从而防止项目崩溃

  • 格式:function(err,req,next){//处理}

  • 注意:错误级别的中间件,必须要注册到所有路由之后

  • 完整代码:

    const express = require("express");
    const app = express();
    //需求:获取到请求到达服务器的时间
    app.get("/api/getbooks", (req, res) => {
      const m = req.query.name.toUpperCase();
      res.send("获取图书列表成功" + m);
    });
    app.post("/api/addbook", (req, res) => {
      res.send("添加图书成功");
    });
    /**
     * 错误中间件:
     *   作用:用来捕获整个项目的异常,从而防止项目崩溃
     *   格式:(err,req,res,next)=>{}
     *   位置:
     *     放到所有路由之后,来捕获异常
     */
    app.use((err, req, res, next) => {
      res.send("服务器错误" + err.message);
    });
    app.listen(3000, () => {
      console.log("http://localhost:3000");
    });

5.4、express内置的中间件:

  1. express.json()中间件

    //通过express.json()中间件,解析表单中JSON格式的数据
    app.use(express.json())

  2. express.urlencoded()中间件

    1. 完整代码:

      const express = require("express");
      const app = express();
      ​
      //通过express.urlencoded()中间件,能够解析application/x-www-form-urlcoded数据格式
      app.use(
        express.urlencoded({
          extended: false,
        })
      );
      // 监听请求
      app.post("/login", (req, res) => {
        // req.body获取的是客户端请求携带的参数(post请求方式携带的参数)
        // req.body在不配置中间件的情况下,获取到是的值是undefined
        // 配置了中间件之后,结果是一个对象  eg:{name:'zs',age:18}
        console.log(req.body);
        res.send("监听了");
      });
      ​
      app.listen(3000, () => {
        console.log("http://locaohost:3000");
      });
      ​

  3. express.static()中间件

六、跨域解决方法:

6.1、cors

  1. 概念:由一系列http响应头组成,http响应头决定浏览器是否阻止js代码跨域获取资源

  2. 在服务器端设置响应头

  3. 完整代码:

    /***
     * 跨域:
     *   概念:协议,域名,端口号有一个不一样就是跨域
     *   原因:浏览器的同源策略,不允许请求非同源的资源
     * 解决方法:
     *   【1】jsonp:
     *       原理:利用script标签的src属性进行跨域,传一个函数名给后台,后台返回的一个函数调用
     *       缺点:只支持get请求,不支持post请求
     *       配合:需要前后台配合完成
     *     前端:
     *       1.定义一个全局函数
     *       2.设置script标签的src,同时要传一个函数名给后台
     *     后台:
     *       返回一个函数调用
     *    【2】cors:  只需要后台完成
     */
    ​
    ​
    const express = require("express");
    ​
    const app = express();
    //配置中间件解决跨域
    // app.use((req, res, next) => {
    //   res.setHeader("Access-Control-Allow-Origin", "*");
    //   res.setHeader("Access-Control-Allow-Headers", "Content-Type");
    //   res.setHeader("Access-Control-Allow-Methods", "*");
    //   next();
    // });
    ​
    // 使用cors第三方包来解决跨域
    const cors = require("cors");
    //注册并使用
    app.use(cors());
    ​
    ​
    app.get("/api/get", (req, res) => {
      res.send("get请求被监听到了");
    });
    app.post("/api/post", (req, res) => {
      res.send("post请求被监听到了");
    });
    app.delete("/api/delete", (req, res) => {
      res.send("delete请求被监听到了");
    });
    // 启动服务器
    app.listen(3000, () => {
      console.log("http://localhost:3000");
    });

6.2、响应头字段:

  1. Access-Control-Allow-Origin字段

    //语法格式
    Access-Control-Allow-Origin:<origin> | *
    origin参数的值指定了允许访问该资源的外域URL
    //限制访问资源的书写方式
    res.setHeader('Access-Control-Allow-Origin','http://www.baidu.com')
    //允许访问任何资源的书写方式
    res.setHeader('Access-Control-Allow-Origin','*')

  2. Access-Control-Allow-Headers字段

    //允许客户端外向服务器发送 Content-Type 请求头和X-Custom-Header请求头
    //注意:多个请求头之间使用英文的逗号分割
    //语法格式:
     res.setHeader('Access-Control-Allow-Headers','Content-Type,X-Custom-Header')

  3. Access-Control-Allow-Methods字段

    //只允许POST、GET、DELETE、HEAD请求方法
    res.setHeader('Access-Control-Allow-Headers','POST,GET,DELETE,HEAD')
    //允许所有的HTTP请求方法
    res.setHeader('Access-Control-Allow-Headers','*')

6.3、请求分类:

  • 简单请求:客户端和服务器之间只发生一次请求

  • 预检请求:客户端和服务器之间会发生两次请求,OPTION预检请求成功之后,才会发起真正的请求

  • 预检的条件:① 请求方式是GET,POST,HEAD之外的请求Method;②请求头中包含自定义头部字段;③向服务器发送了application/json格式的数据

6.4、jsonp:

  1. 特点:①只支持get请求,不支持post,put等其他的请求;②jsonp不是真正的ajax请求;

  2. 原理:通过script标签的src属性,传给一个函数名给后台,后台返回一个函数调用

  3. 完整代码:

    const express = require("express");
    const app = express();
    ​
    // 挂载路由
    app.get("/api/jsonp", (req, res) => {
      /**
       * 返回是一个函数调用jQueryxxx({})
       * 思路:
       *   1.获取客户端发送过来的函数名req.query.callback
       *   2.自己定义一个数据
       *   3.拼接一个函数的调用形式
       *   4.响应回去
       */
      //1.获取客户端发送过来的函数名req.query.callback
      const { callback } = req.query;
      // 2.自己定义一个数据
      const obj = { name: "zs", age: 18 };
      //3.拼接一个函数的调用形式
      const str = `${callback}(${JSON.stringify(obj)})`;
      res.send(str);
    });
    ​
    app.listen(3000, () => {
      console.log("http://localhost:3000");
    });

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值