Danmo的学习之路(node.js)

观看黑马node.js教程

3.4

执行node(P6)

  • 代码写在js文件内
  • 在该js所在文件夹内git bash here,输入 node 文件名

文件名不能叫node.js,否则执行命令后,会打开js文件

node 01.js	//hello world!

读取文件(P7)

let fs = require('fs');
fs.readFile('./txt文件/01.txt',function(error,data){
    if(error){
        console.log('Error!');
    }
    else{
        console.log(data.toString());
    }
});

在这里插入图片描述

简单http服务(P8)

let http = require('http');         //引入http模块
let server = http.createServer();   //创建服务器
server.on('request',function(){
    console.log("接收到请求");
})
server.listen(3000,function(){      //3000是端口号
    console.log('服务器启动成功,可以通过 http://127.0.0.1:3000/ 来进行访问');
})

在这里插入图片描述
先输入node …
然后把该url复制到浏览器最上方框框内,回车,跳出"接收到请求"

ctrl + c 关闭服务器

发送响应(P9)

let http = require('http');         //引入http模块
let server = http.createServer();   //创建服务器
server.on('request',function(request, response){
    console.log("接收到请求,路径是:" + request.url);
    let reg01 = new RegExp("login","i");
    let reg02 = new RegExp("register","i");
    let reg03 = new RegExp("haha","i");
    console.log()
    if(reg01.test(request.url)){
        //可以let url = request.url,可以变得更简洁
        response.write("login!");
    }
    if(reg02.test(request.url)){
        response.write("register!");
    }
    if(reg03.test(request.url)){
        response.write("Hahahaha!");  
    }
    response.end();
    //可以end的同时发送响应数据,如response.end("hello world") 等价于先write再end
})
server.listen(3000,function(){      //3000是端口号
    console.log('服务器启动成功,可以通过 http://127.0.0.1:3000/ 来进行访问');
})

在这里插入图片描述

在这里插入图片描述

发送对象(P11)

let http = require('http');         //引入http模块
let server = http.createServer();   //创建服务器
server.on('request',function(req,res){
    console.log('收到请求了,请求路径是:' + req.url);
    let url = req.url;
    let reg01 = new RegExp("products","i");
    if(reg01.test(url)){
        let productsArr = [{
            name: 'Apple X',
            price: 8888
        },
        {
            name: 'Pine X',
            price: 5000
        },
        {
            name: 'Chili X',
            price: 1999
        }
        ]
        res.end(JSON.stringify(productsArr));
    }
    else{
        res.end("404 Not Found !");
    }
})
server.listen(3000,function(){      //3000是端口号
    console.log('服务器启动成功,可以通过 http://127.0.0.1:3000/ 来进行访问');
})

在这里插入图片描述

模块系统(P13)

除了引入核心模块,require可以在一个文件中引入另一个文件,但是存在模块作用域,即外部访问不到内部,内部也访问不到外部

想让模块间通信时,可以在被引文件中写入exports,如 a文件引入了b文件 require(’./b’),那么b文件内可以:

exports.foo = 'hello';
exports.add = function(x,y){
	return x + y;
}

a文件内:

let bExports = require('./b');
console.log(bExports.foo);//hello

3.5

ip地址和端口号(P14)

ip地址定位某一台计算机,端口号定位该计算机上的应用程序

//写在server.on函数内:
    console.log('请求我的客户端的地是',req.socket.remoteAddress,req.socket.remotePort);
    //获取ip地址和端口号

只要发送请求,服务器就能获得ip地址和端口号
在这里插入图片描述

响应内容类型(P16)

let http = require('http');
let server = http.createServer();
server.on('request',function(req,res){
    let url = req.url;
    if(url === '/plain'){   //普通文本
        res.setHeader('Content-Type','text/plain;charset=utf-8');   
        //防止乱码,引号内不能多空格
        res.end('一行中文文本');
    }
    else if(url === '/html'){   //html
        res.setHeader('Content-Type','text/html;charset=utf-8');
        res.end('<h1>一段HTML</h1>');
    }
})
server.listen(3000,function(){
    console.log('Server is running...');
    console.log('服务器启动成功,可以通过 http://127.0.0.1:3000/ 来进行访问');
})

在这里插入图片描述

响应图片(P17)

let http = require('http');
let fs = require('fs'); //引入fs核心模块
let server = http.createServer();
server.on('request',function(req,res){
    let url = req.url;
    if(url === '/html'){
        fs.readFile('./html/02.html',function(err,data){
            if(err){
                res.setHeader('Content-Type','text/plain;charset=utf-8');
                res.end('文件读取失败,请稍后重试!');
            }
            else{
                res.setHeader('Content-Type','text/html;charset=utf-8');
                res.end(data);  //html文件无需tostring
                //修改html文件时,只需要在浏览器内刷新就能看到,不需要重开服务器,其它资源都同理
                //只有修改了该js文件后,才需要重启服务器
            }
        })    
    }
    else if(url === '/img'){
        fs.readFile('./imgs/1.jpg',function(err,data){
            if(err){
                res.setHeader('Content-Type','text/plain;charset=utf-8');
                res.end('文件读取失败,请稍后重试!');
            }
            else{
                res.setHeader('Content-Type','image/jpeg');
                res.end(data);  //img文件也无需tostring
            }
        })
    }
});
server.listen(3000,function(){
    console.log('服务器启动成功,可以通过 http://127.0.0.1:3000/ 来进行访问');
})

在这里插入图片描述

第一天总结(P18)

## 上午总结

- Node.js 是什么
  + JavaScript 运行时
  + 既不是语言,也不是框架,它是一个平台
- Node.js 中的 JavaScript
  + 没有 BOM、DOM
  + EcmaScript 基本的 JavaScript 语言部分
  + 在 Node 中为 JavaScript 提供了一些服务器级别的 API
    * 文件操作的能力
    * http 服务的能力

## 总结

- Node 中的 JavaScript
  + EcmaScript
    * 变量
    * 方法
    * 数据类型
    * 内置对象
    * Array
    * Object
    * Date
    * Math
  + 模块系统
    * 在 Node 中没有全局作用域的概念
    * 在 Node 中,只能通过 require 方法来加载执行多个 JavaScript 脚本文件
    * require 加载只能是执行其中的代码,文件与文件之间由于是模块作用域,所以不会有污染的问题
      - 模块完全是封闭的
      - 外部无法访问内部
      - 内部也无法访问外部
    * 模块作用域固然带来了一些好处,可以加载执行多个文件,可以完全避免变量命名冲突污染的问题
    * 但是某些情况下,模块与模块是需要进行通信的
    * 在每个模块中,都提供了一个对象:`exports`
    * 该对象默认是一个空对象
    * 你要做的就是把需要被外部访问使用的成员手动的挂载到 `exports` 接口对象中
    * 然后谁来 `require` 这个模块,谁就可以得到模块内部的 `exports` 接口对象
    * 还有其它的一些规则,具体后面讲,以及如何在项目中去使用这种编程方式,会通过后面的案例来处理
  + 核心模块
    * 核心模块是由 Node 提供的一个个的具名的模块,它们都有自己特殊的名称标识,例如
      - fs 文件操作模块
      - http 网络服务构建模块
      - os 操作系统信息模块
      - path 路径处理模块
      - 。。。。
    * 所有核心模块在使用的时候都必须手动的先使用 `require` 方法来加载,然后才可以使用,例如:
      - `var fs = require('fs')`
- http
  + require
  + 端口号
    * ip 地址定位计算机
    * 端口号定位具体的应用程序
  + Content-Type
    * 服务器最好把每次响应的数据是什么内容类型都告诉客户端,而且要正确的告诉
    * 不同的资源对应的 Content-Type 是不一样,具体参照:http://tool.oschina.net/commons
    * 对于文本类型的数据,最好都加上编码,目的是为了防止中文解析乱码问题
  + 通过网络发送文件
    * 发送的并不是文件,本质上来讲发送是文件的内容
    * 当浏览器收到服务器响应内容之后,就会根据你的 Content-Type 进行对应的解析处理

- 模块系统
- Node 中的其它的核心模块
- 做一个小管理系统:
  + CRUD
- Express Web 开发框架
  + `npm install express`

初步实现Apache(P21)

  • apache软件默认有www目录,所有存放在www目录中的资源都可以通过网址来浏览
  • 这样就能省去很多if判断了,输什么就能找到什么资源
let http = require('http');
let fs = require('fs');
let server = http.createServer();

let dir = 'D:/程序小白进阶之路/node.js';

server.on('request',function(req,res){
    let url = req.url;
    let filePath = '/html/02.html';
    if(url !== '/'){
        filePath = url;
    }
    fs.readFile(dir + filePath, function(err,data){
        if(err){
            return res.end('404 Not Found.');
        }
        res.end(data);
    })
})
server.listen(3000,function(){
    console.log('服务器启动成功,可以通过 http://127.0.0.1:3000/ 来进行访问');
})

显示目录(P23)

先把文件夹拖入浏览器,然后获取其http,删除所有script,得到模板

<!DOCTYPE html>
<html dir="ltr" lang="zh">
<head>
  <meta charset="utf-8">
  <meta name="google" value="notranslate">
  <style>
    h1 {
      border-bottom: 1px solid #c0c0c0;
      margin-bottom: 10px;
      padding-bottom: 10px;
      white-space: nowrap;
    }

    table {
      border-collapse: collapse;
    }

    th {
      cursor: pointer;
    }

    td.detailsColumn {
      -webkit-padding-start: 2em;
      text-align: end;
      white-space: nowrap;
    }

    a.icon {
      -webkit-padding-start: 1.5em;
      text-decoration: none;
      user-select: auto;
    }

    a.icon:hover {
      text-decoration: underline;
    }

    a.file {
      background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAABHUlEQVR42o2RMW7DIBiF3498iHRJD5JKHurL+CRVBp+i2T16tTynF2gO0KSb5ZrBBl4HHDBuK/WXACH4eO9/CAAAbdvijzLGNE1TVZXfZuHg6XCAQESAZXbOKaXO57eiKG6ft9PrKQIkCQqFoIiQFBGlFIB5nvM8t9aOX2Nd18oDzjnPgCDpn/BH4zh2XZdlWVmWiUK4IgCBoFMUz9eP6zRN75cLgEQhcmTQIbl72O0f9865qLAAsURAAgKBJKEtgLXWvyjLuFsThCSstb8rBCaAQhDYWgIZ7myM+TUBjDHrHlZcbMYYk34cN0YSLcgS+wL0fe9TXDMbY33fR2AYBvyQ8L0Gk8MwREBrTfKe4TpTzwhArXWi8HI84h/1DfwI5mhxJamFAAAAAElFTkSuQmCC ") left top no-repeat;
    }

    a.dir {
      background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAd5JREFUeNqMU79rFUEQ/vbuodFEEkzAImBpkUabFP4ldpaJhZXYm/RiZWsv/hkWFglBUyTIgyAIIfgIRjHv3r39MePM7N3LcbxAFvZ2b2bn22/mm3XMjF+HL3YW7q28YSIw8mBKoBihhhgCsoORot9d3/ywg3YowMXwNde/PzGnk2vn6PitrT+/PGeNaecg4+qNY3D43vy16A5wDDd4Aqg/ngmrjl/GoN0U5V1QquHQG3q+TPDVhVwyBffcmQGJmSVfyZk7R3SngI4JKfwDJ2+05zIg8gbiereTZRHhJ5KCMOwDFLjhoBTn2g0ghagfKeIYJDPFyibJVBtTREwq60SpYvh5++PpwatHsxSm9QRLSQpEVSd7/TYJUb49TX7gztpjjEffnoVw66+Ytovs14Yp7HaKmUXeX9rKUoMoLNW3srqI5fWn8JejrVkK0QcrkFLOgS39yoKUQe292WJ1guUHG8K2o8K00oO1BTvXoW4yasclUTgZYJY9aFNfAThX5CZRmczAV52oAPoupHhWRIUUAOoyUIlYVaAa/VbLbyiZUiyFbjQFNwiZQSGl4IDy9sO5Wrty0QLKhdZPxmgGcDo8ejn+c/6eiK9poz15Kw7Dr/vN/z6W7q++091/AQYA5mZ8GYJ9K0AAAAAASUVORK5CYII= ") left top no-repeat;
    }

    a.up {
      background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmlJREFUeNpsU0toU0EUPfPysx/tTxuDH9SCWhUDooIbd7oRUUTMouqi2iIoCO6lceHWhegy4EJFinWjrlQUpVm0IIoFpVDEIthm0dpikpf3ZuZ6Z94nrXhhMjM3c8895977BBHB2PznK8WPtDgyWH5q77cPH8PpdXuhpQT4ifR9u5sfJb1bmw6VivahATDrxcRZ2njfoaMv+2j7mLDn93MPiNRMvGbL18L9IpF8h9/TN+EYkMffSiOXJ5+hkD+PdqcLpICWHOHc2CC+LEyA/K+cKQMnlQHJX8wqYG3MAJy88Wa4OLDvEqAEOpJd0LxHIMdHBziowSwVlF8D6QaicK01krw/JynwcKoEwZczewroTvZirlKJs5CqQ5CG8pb57FnJUA0LYCXMX5fibd+p8LWDDemcPZbzQyjvH+Ki1TlIciElA7ghwLKV4kRZstt2sANWRjYTAGzuP2hXZFpJ/GsxgGJ0ox1aoFWsDXyyxqCs26+ydmagFN/rRjymJ1898bzGzmQE0HCZpmk5A0RFIv8Pn0WYPsiu6t/Rsj6PauVTwffTSzGAGZhUG2F06hEc9ibS7OPMNp6ErYFlKavo7MkhmTqCxZ/jwzGA9Hx82H2BZSw1NTN9Gx8ycHkajU/7M+jInsDC7DiaEmo1bNl1AMr9ASFgqVu9MCTIzoGUimXVAnnaN0PdBBDCCYbEtMk6wkpQwIG0sn0PQIUF4GsTwLSIFKNqF6DVrQq+IWVrQDxAYQC/1SsYOI4pOxKZrfifiUSbDUisif7XlpGIPufXd/uvdvZm760M0no1FZcnrzUdjw7au3vu/BVgAFLXeuTxhTXVAAAAAElFTkSuQmCC ") left top no-repeat;
    }

    html[dir=rtl] a {
      background-position-x: right;
    }

    #parentDirLinkBox {
      margin-bottom: 10px;
      padding-bottom: 10px;
    }

    #listingParsingErrorBox {
      border: 1px solid black;
      background: #fae691;
      padding: 10px;
      display: none;
    }
  </style>
  <title id="title"></title>
</head>
<body>
  <div id="listingParsingErrorBox">糟糕!Google Chrome无法解读服务器所发送的数据。请<a
      href="http://code.google.com/p/chromium/issues/entry">报告错误</a>,并附上<a href="LOCATION">原始列表</a></div>
  <h1 id="header">D:/程序小白进阶之路/node.js/的索引</h1>
  <div id="parentDirLinkBox" style="display:none">
    <a id="parentDirLink" class="icon up">
      <span id="parentDirText">[上级目录]</span>
    </a>
  </div>
  <table>
    <thead>
      <tr class="header" id="theader">
        <th id="nameColumnHeader" tabindex=0 role="button">名称</th>
        <th id="sizeColumnHeader" class="detailsColumn" tabindex=0 role="button">
          大小
        </th>
        <th id="dateColumnHeader" class="detailsColumn" tabindex=0 role="button">
          修改日期
        </th>
      </tr>
    </thead>
    <tbody id="tbody">^_^</tbody>
    <!--这里的^_^是后加的,用于替换-->
  </table>
</body>
</html>
let http = require('http');
let fs = require('fs');
let server = http.createServer();
let wwwDir = 'D:/程序小白进阶之路/node.js';
server.on('request',function(req,res){
    let url = req.url;
    fs.readFile('./html/目录模板.html', function(err,data){
        if(err){
            return res.end('404 Not Found.');
        }
        fs.readdir(wwwDir,function(err,files){
            if(err){
                return res.end('Can not find www dir.');
            }
            let content = '';
            files.forEach(function(item){
                content += `
                <tr>
                  <td data-value="apple/"><a class="icon dir" href="D:/程序小白进阶之路/node.js/">${item}/</a></td>
                  <td class="detailsColumn" data-value="0"></td>
                  <td class="detailsColumn" data-value="1509589967">2021/3/6 下午19:05:47</td>
                </tr>
              `
            });
            data = data.toString();
            data = data.replace('^_^',content);
            //把笑脸替换成目录
            res.end(data);
        });
    });
})
server.listen(3000, function () {
    console.log('服务器启动成功,可以通过 http://127.0.0.1:3000/ 来进行访问');
  })

在这里插入图片描述

在浏览器中使用art-template(P24)

下载模板引擎的方法:在想要下载的目录,git bash here,npm install art-template

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./template/node_modules/art-template/lib/template-web.js"></script>
    <script type="text/template" id="tpl">
        <!DOCTYPE html>
        <html lang="en">
        <head>
          <meta charset="UTF-8">
          <title>Document</title>
        </head>
        <body>
          <p>大家好,我叫:{{ name }}</p>
          <p>我今年 {{ age }} 岁了</p>
          <h1>我来自 {{ school }}</h1>
          <p>我喜欢:{{each hobbies}} {{ $value }} {{/each}}</p>
        </body>
        </html>
      </script>
      <script>
        var ret = template('tpl', {
          name: 'Danmo',
          age: 19,
          school: '华中科技大学',
          hobbies: [
            '玩游戏',
            '写代码',
            '看动漫'
          ]
        })
        console.log(ret);
    </script>
</head>
<body>
</body>
</html>

在node中使用art-template(P25)

let template = require('art-template')
let fs = require('fs')
fs.readFile('./html/03.html', function (err, data) {
    if (err) {
        return console.log('读取文件失败')
    }
    //render是模板引擎的方法,需要传入一个字符串
    let ret =  template.render(data.toString(), {
        name: 'Danmo',
        age: 18,
        province: '',
        hobbies: [
          '写代码',
          '唱歌',
          '打游戏'
        ],
        title: '个人信息'
    })
    console.log(ret)
}) 

在这里插入图片描述

模板引擎读取目录(P26)

let http = require('http')
let fs = require('fs')
let template = require('art-template')
let server = http.createServer()
let wwwDir = 'D:/程序小白进阶之路/node.js'
server.on('request', function (req, res) {
    let url = req.url
    fs.readFile('./html/template02.html', function (err, data) {
        if (err) {
            return res.end('404 Not Found.')
        }
        fs.readdir(wwwDir, function (err, files) {
            if (err) {
                return res.end('Cannot find dir.')
            }
            let htmlStr = template.render(data.toString(), {
                title: '目录',
                files: files
            })
            res.end(htmlStr)
        })
    })
})
server.listen(3000, function () {
    console.log('服务器启动成功,可以通过 http://127.0.0.1:3000/ 来进行访问')
})

node中的REPL(P34)

在这里插入图片描述

像浏览器的控制台一样,在任意目录下打开命令行窗口,输入node,即可进行REPL,退出时两次ctrl+c

read eval print loop(读取 执行 打印 等待下一次输入)

它的作用,主要是作一些API的测试

导出单个成员(P39)

  • 之前说过的exports.xxx = … 导出的时候是一个对象,A文件内使用方法或属性还需要’点儿’

  • 如果要直接导出函数、字符串等,可以用modules.exports,这个方法可以导出单个成员,如果有多个modules.exports,则下面会覆盖上面

A文件:

modules.exports = 'hello'

B文件:

let fooExports = require('./foo')
console.log(fooExports)	//'hello'

modules.exports和exports的原理(P40)

只需记住以下要点:

  • 因为每次写的 ‘.’ 太多了,node在模块内加了一句:exports = modules.exports
  • 最后return的是modules.exports
  • 对于引用数据类型,exports和modules.exports都相当于指针,如果直接对exports或者modules.exports赋值,指针就会指向别处;只要指针指向同一块区域,就可以随意为其添加属性和方法

这里关键是,对“引用数据类型”的理解

require加载规则(P42、P43)

优先从缓存加载

如果一个文件已经require过了,则不会再次加载该文件,再次require的意义,在于得到接口对象(let obj = require(…),目的在于得到obj)

第三方包查找规则

  • 先找到当前文件所处目录中的 node_modules 目录
  • 检索require(’ ')引号内的字符串,找到并进入该目录,比如我require(‘art-template’),就会进入/node_modules下的art-template目录
  • 找package.json文件,找该文件内的"main",如果写的是"main":“foo.js”,就会加载foo.js中的内容,真正的代码是写在这个foo.js中的
  • 如果找不到package.json文件,或者main指定的入口模块不存在,则默认加载index.js(index.js是默认备选项),如果index.js也没有,继续往上一级目录的node_modules目录中查找,如果直到当前磁盘根目录都没找到,就报错:can not find module

在项目中,一般只会在项目根目录下有一个node_modules目录

npm包(P44、P45、P46)

更多资料:Npm菜鸟教程

npm:node package manager

包说明文件

  • package.json文件是包说明文件,建议每个项目都有一个,存放在项目根目录,从这个文件,可以得到包括 项目依赖哪些第三包… 等等的信息
  • npm init 初始化项目即可生成package.json文件,这是个向导型命令,一问一答。

npm init

npm install 包名 --save

  • 添加–save时,会在package.json文件中添加"dependencies",从它我们可以看出该项目依赖了哪些第三方包,建议每次都添加–save
  • 如果有"dependencies",将 node_modules文件夹误删除时,可以直接通过npm install 将所有依赖的第三方包下载回来

npm常用命令补充

  • npm init -y 可以跳过向导,快速初始化
  • npm i -S(install --save的缩写)
  • npm i --global npm 不升级node,只升级npm版本(也可以用 -g)
  • npm uninstall(缩写是un)
  • npm help 查看使用帮助
    • npm 命令 --help 查看指定命令的使用帮助

解决npm被墙问题

我不觉得npm下载速度慢,故这里先mark

-g 全局安装和本地安装的区别

npm的安装分为全局模式本地模式

一般情况下会以本地模式运行,包会被安装到和 应用程序代码的本地node_modules目录 下。

在全局模式下,Node包会被安装到 Node的安装目录下的node_modules 下。

全局安装命令为$npm install -g moduleName。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值