NodeJS

一. 安装及概述 1. 概述: Node.js 不是一门新的语言,是一个JavaScript运行环境, 简单的说 Node.js 就是运行在服务端的 JavaScript。 2. 特点: 1).单线程 2).异步的非阻塞I/O 3).事件驱动 3. 使用场景: 1).后台开发 2).使用node的npm功能,方便的安装,删除,替换第三方模块 3).node的兼容性较好,Windows,Linux,MacOS均可以使用node环境,node从 0.6版本开始,只要装node,会顺带装npm 二. 模块 1. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Node环境中,一个.js文件就称之为一个模块(module)。 2. 好处: 最大的好处是大大提高了代码的可维护性。其次,编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。我们在编写程序的时候,也经常引用其他模块,包括Node内置的模块和来自第三方的模块。使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中,因此,我们自己在编写模块时,不必考虑名字会与其他模块冲突。 3. 注意: exports 和 module.exports 的使用 如果要对外暴露属性或方法,就用 exports 就行,要暴露对象(类似class,包含了很多属性和方法),就用 module.exports。

exports与module.exports的区别: * exports是对module.exports的引用 * 外界require导入模块时,真正导入的是module.exports而不是exports

exports与module.exports的区别: * 1.exports是对module.exports的引用 * 2.外界require导入模块时,真正导入的是module.exports而不是exports 4. http模块 分析Node.js 的 HTTP 服务器: 第一行请求(require)Node.js 自带的 http 模块,并且把它赋值给 http 变量。 接下来我们调用 http 模块提供的函数:createServer 。这个函数会返回 一个对象,这个对象有一个叫做 listen 的方法,这个方法有一个数值参数, 指定这个 HTTP 服务器监听的端口号。 例: let http=require("http"); http.createServer(function (req,res) {}).listen(端口号);

http协议:

let http=require("http");
/*
* http协议:基于请求和响应的模式,如果服务器响应完毕,客户端与服务器断开连接,下次请求需要重新发起请求,http是典型的短连接
*
* createServer分两部分:
1.创建server
2.设置监听

req(requet对象)--请求对象
    请求头/请求体
    请求头:请求头很短,包含本次请求的基本信息
    常用的req对象属性:
    url--当前请求的路径和参数
    method--当前请求的方式

    请求体:当POST请求时,数据会存放在请求体里传送到后台,但是因为数据会很大,node不会依次传递完毕,会分段传递,所以我们需要监听两个事件保证数据获取的完整性和准确性
    data--每当有一段数据传递过来时,data事件都会触发
    end--当最后一段数据传递完毕时,end事件会触发

res(response对象)--响应对象
    响应头/响应体
    响应头:存储本次响应给前端数据的配置信息,如文件格式,编码格式等
    res.writeHeader(响应码, {配置信息});第二个参数苏也可以不写.系统也会自动加一个,但是值是默认值

    响应体:决定后台向前端返回什么

    res.write()--可以写多次,也可以不写
    res.end()--必须写,作用是结束本次响应,如果不写,前端会一直等待后台响应
* */

let server=http.createServer(function (req,res) {
    console.log(req.url,req.method);
    res.end("响应结束");
}).listen(7890);

//监听端口号
// server.listen(7890);

5.fs模块

6.node.js的核心思想之一: 模块(module)和包(package)

模块的本质是一个文件,该文件的类型可以是js,json,也可以是其他语言编译过后的文件(c,c++).

node对包的管理,遵循的是commonJS规范(规定了js脱离浏览器端之后的一些书写标准)

* 优点:方便代码的抽离和使用. * 为了方便实现模块化,node给每个文件都设置了requir和exports功能. * import 导入,export 导出 * require是为了引入外部的模块 * exports是当前文件如果被别的文件引入时的入口对象,而且是唯一入口对象

包的本质是一个文件夹(目录),包是由多个模块组成,npm管理的就是包

node对包的管理,遵循的是commonJS规范(规定了js脱离浏览器端之后的一些书写标准)

ECMSScript6====ECMAScript2015

commonJS规定,在创建或者下载包时,每个包里必须要有一个package.json文件,该文件里存储了与本包有关的所有配置信息(如包的入口文件) * node允许我们使用交互式的方式创建package.json文件 1.cd 文件夹路径 2. npm init / npm init -y

/* * 下载第三方的命令: * 1. npm i 包名 -- 下载包 * 2. npm i 包名@版本号 -- 下载对应版本的包 * 3. npm uni 包名 -- 移除包 * 4. npm uni 包名@版本号 -- 移除对应版本的包 * 5. npm i -- 根据package.json,安装所有包 * */

7.path模块

//引入path模块
//path  node里专门用来处理路径的模块
let path=require("path");

//1.规范化路径
let pathStr='./a/b/c/../d';
let str=path.normalize(pathStr);
console.log(str);

//2.拼接路径
let str1=path.join("./","a/","b/","c/../","d");
console.log(str1);

//3.__dirname, __filename  这是node提供的全局变量,与path没有关系
console.log(__dirname, __filename);

//4.判断一个路径是否是绝对路径,以 / 开头的都是绝对路径
console.log(path.isAbsolute('a/b/c'));

//5.获取一个路径到另外一个路径之间的相对路径
let str2=path.relative("a/b/c/d/e","a/f/g");
console.log(str2);

//6. 获取当前文件所处的目录
let str3=path.dirname("a/b/c/d/n.txt");
console.log(str3);

//7.获取对应文件所在的路径中的最后一个部分
let str4=path.basename(__filename);
console.log(str4);

//8.获取对应文件的后缀
let str5=path.extname(__filename);
console.log(str5);

//9.对路径字符串进行解析  字符串-->对象
let str6=path.parse(__filename);
console.log(str6);

//10.对路径对象进行编码  对象-->字符串
let pathObj={
    root: 'C:\\',
    dir: 'C:\\Users\\lx\\Desktop\\a\\b',
    base: 'c.html',
    ext: '.html',
    name: 'c'
};
let str7=path.format(pathObj);
console.log(str7);

8.url模块

let urlStr="http://www.baidu.com:8888/a/b/c/d/index.hmtl?name=nihao#sPage";
// #:哈希值,该值不会传递到服务器

//url模块,node里专门用来处理URL网址的模块
let url=require("url");
//1.将URL地址转化为对象
/*
* protocol: 'http:',                协议名
  slashes: true,                    协议名后面是否有斜杠
  auth: null,                       认证授权
  host: 'www.baidu.com:8888',       域名+端口号
  port: '8888',                     端口号
  hostname: 'www.baidu.com',        域名
  hash: '#sPage',                   哈希值
  search: '?name=nihao',            ?+参数列表
  query: 'name=nihao',              参数列表
  pathname: '/a/b/c/d/index.hmtl',  路径
  path: '/a/b/c/d/index.hmtl?name=nihao',                                               路径+?+参数列表
  href:
   'http://www.baidu.com:8888/a/b/c/d/index.hmtl?name=nihao#sPage'             完整的url
* */

//parse方法的第二个参数是一个布尔值,作用,如果填true会把urlObj里query字段转化为对象
let urlObj=url.parse(urlStr,true);
console.log(urlObj.query.name);

三. 事件 events 模块只提供了一个对象:events.EventEmitter。EventEmitter 的核心就 是事件发射与事件监听器功能的封装。 EventEmitter 的每个事件由一个事件名和若干个参 数组成,事件名是一个字符串,通常表达一定的语义。对于每个事件,EventEmitter 支持 若干个事件监听器。 当事件发射时,注册到这个事件的事件监听器被依次调用,事件参数作 为回调函数参数传递。 EventEmitter.on(event, listener)、emitter.addListener(event, listener) 为指定事件注册一个监听器,接受一个字 符串 event 和一个回调函数 listener。 四. get/post请求 get请求 var http = require('http'); var url = require('url'); var util = require('util'); http.createServer(function(req, res){ res.writeHead(200, {'Content-Type': 'text/plain'}); res.end(util.inspect(url.parse(req.url, true))); }).listen(3000); ------------------------------------------- post请求 var http = require('http'); var querystring = require('querystring'); var util = require('util'); http.createServer(function(req, res){ var post = ''; //定义了一个post变量,用于暂存请求体的信息 req.on('data', function(chunk){ //通过req的data事件监听函数,每当接受到请求体的数据,就累加到post变量中 post += chunk; }); req.on('end', function(){ //在end事件触发后,通过querystring.parse将post解析为真正的POST请求格式,然后向客户端返回。 post = querystring.parse(post); res.end(util.inspect(post)); }); }).listen(3000);

四. express

express模块--是node里对http模块的再次封装 Express是一个自身功能极简,完全是路由和中间件构成一个web开发框架:从本质上来说,一个Express应用就是在调用各种中间件

express.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>express框架</title>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
    <button>ajax_get</button>
    <button>ajax_post</button>
    <button>ajax_jsonp</button>
    <script type="text/javascript">
        $("button").eq(0).click(function () {
            $.ajax({
               url:"http://127.0.0.1:3333/ajaxGet",
               type:"get",
               data:{name:"nihao",age:20},
               success:function (data) {
                   console.log(data);
               }
            });
        });
        $("button").eq(1).click(function () {
            $.ajax({
                url:"http://127.0.0.1:3333/ajaxPost",
                type:"post",
                data:{id:123,school:"郑州大学"},
                success:function (data) {
                    console.log(data);
                }
            });
        });
        $("button").eq(2).click(function () {
            $.ajax({
                url:"http://127.0.0.1:3333/ajaxJsonp",
                type:"get",
                dataType:"jsonp",
                //express发起jsonp请求时,jsonp字段为callback,不能修改或者省略jsonp字段,默认值就是callback
                jsonp:"callback",
                jsonpCallback:"getData"
            });
        });
        function getData(data) {
            console.log(data);
        }
</script>
</body>
</html>

express.Jjs

let express=require("express");
//node里的querystring模块,专门用来处理参数字符串
// let qs=require("querystring");

//创建服务器
let app=express();
//1.引入body-parser模块
var bp = require('body-parser');
//2.配置body-parser,让所有的post请求都支持body-parser模块,那么所有的req对象就会多一个body属性,里面存储了post请求过来的数据     如何让所有的路由都支持body-parser模块?--使用中间件实现
app.use(bp.urlencoded({extended:false}));
/*
* express方法调用返回的app有三个监听方法,实现了类似路由的功能,但是本质还是中间件
* get()--用来监听get请求
* post()--用来监听post请求
* all()--用来监听所有请求,一半用来处理跨域问题
*
* 监听方法的参数:
* 参数一:路由
*   a.字符串,如"/favicon.ico","/2-ajax.html"."*";
*   b.正则表达式
* 参数二:回调函数
*   req对象:请求对象--常用属性:
*       1.query 参数对象
*       2.path 文件路径
*       3.hostname 服务器地址
*    res对象:响应对象--常用方法:
*       1.res.json(对象)
*       2.res.jsonp(对象)
*       3.res.send(内容)
*       4.res.sendFile(文件路径)
*       5.res.setHeader()--设置响应头
* */
//响应首部 Access-Control-Allow-Headers 用于 preflight request (预检请求)中,列出了将会在正式请求的 Access-Control-Expose-Headers 字段中出现的首部信息。简单首部,如 simple headers、Accept、Accept-Language、Content-Language、Content-Type (只限于解析后的值为 application/x-www-form-urlencoded、multipart/form-data 或 text/plain 三种MIME类型(不包括参数)),它们始终是被支持的,不需要在这个首部特意列出。
app.all("*",function (req,res,next) {
    res.setHeader("Access-Control-Allow-Origin","*");
    res.setHeader("Access-Control-Allow-Header","X-Requested-With");
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST,PUT,DELETE,OPTIONS');
    next();
});
app.get("/",function (req,res) {
    res.end("响应结束");
});
app.get(/^\/.+\.html$/,function (req,res) {
    res.sendFile(__dirname+req.path);
    // console.log(__dirname);
});
app.get("/favicon.ico",function (req,res) {
    res.sendFile(__dirname+req.path);
});
app.get("/ajaxGet",function (req,res) {
    if(req.query.name=="nihao" && req.query.age=="20"){
        res.json({msg:"登陆成功"});
    }else{
        res.send("登录失败");
    }
});
app.post("/ajaxPost",function (req,res) {
    //express里,post请求来的数据不存放在req.query里,post的数据存储在req对象的body属性里,但是需要bodyparser模块的配合
    /*var allData="";
    req.on("data",function (chunk) {
        allData+=chunk;
    })
    req.on("end",function () {
        let queryObj=qs.parse(allData);
        res.send(queryObj.id+queryObj.school);
    })*/
    // console.log(req.body);
    if(req.body.id=="123" && req.body.school=="郑州大学"){
        res.json({
            msg:"登陆成功",
        });
    }else{
        res.send("登录失败");
    }
});
app.get("/ajaxJsonp",function (req,res) {
    res.jsonp({id:123,name:"nihao",age:20,sex:"男"});
});

/*
* 中间件--语法:
* app.use(路由(可省略),回调函数(req,res,next));
* 中间件是在请求的开始和请求的结束之间插入一些额外的操作
* 使用场景:
* 1.处理特殊的请求设置,body-parser
* 2.实现CORS 跨域资源共享(cross-origin-resource-sharing)
* */

//监听端口
app.listen(3333);

用到更多:

1.安装模块命令后面为什么要加 --save??

--save表示,我们安装模块的时候,同时把它写到package.json 文件中。这时打开package.json 文件,我们看到多了一个dependencies字段,它包括了我们刚安装的express dependencies: 是项目运行时的依赖,就是程序上线后仍然需要依赖,比如express, 我们程序就是用express 写的,如果没有express, 我们的程序根本无法运行,更直白一点,dependencies 就是我们在程序开发的过程中手动require的模块

原文发布于微信公众号 - 生南星(gh_36d61425a5dc)

原文发表时间:2019-04-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券