美文网首页
三、node(一)

三、node(一)

作者: sheepmiee | 来源:发表于2017-02-24 23:50 被阅读70次

Node的安装

把NODE安装后,如果我们没有修改安装的目录,那么默认是安装在:C:\Program Files\nodejs (大部分都是,如果自己修改了安装目录,自己去查找即可)

如果我们安装了NODE,那么它默认会把命令集成到DOS命令中,也就是DOS窗口中可以执行NODE命令

如果没有集成到DOS中,说明环境变量中缺少执行的文件,需要我们配置环境变量:

[WIN7]配置环境变量
我的电脑(右键) -> 高级系统设置 -> 环境变量

系统变量 -> Path -> 把原有的变量值保存一份

把NODE安装的目录添加到原有值的后面,例如:...;C:\Program Files\nodejs\

在把最新的结果重新写入到环境变量值中

Node的基本信息

何为NODE

NODE其实并非后台开发语言,我们了解的JAVA、PHP、C#、.NET(dot net)...才是后台开发语言,NODE仅仅是一个工具,一个基于V8引擎来渲染和解析JS的平台和工具(有点类似浏览器)
真实的开发中,我们一般都把NODE安装在服务器端,这样我们就可以在服务器端编写一些JS代码来处理服务器端的业务逻辑了 =>JS不仅仅可以在客户端浏览器中运行处理客户端业务逻辑(前端开发语言),也可以在服务器端的NODE环境下运行处理服务器端业务逻辑(后台开发语言),所以JS是全栈开发语言

NODE如何去执行JS代码

  • 直接利用WB:在JS的空白处,右键,找到 Run xxx.js 就是在WB中调取NODE环境执行我们的JS代码
  • 在当前JS所在的文件目录中打开DOS窗口,在DOS中执行 node xxx.js 也相当于把JS代码在NODE环境下执行了
  • NODE的REPL命令:打开命令行输入node,出现 ‘ > ’说明已经进入了REPL

REPL(Read-Eval-Print Loop,简称REPL,“读取-求值-输出”循环)是一个简单的,交互式的编程环境。
REPL既可以作为独立单机程序,也可以被其他的程序包含在内的程序。
它提供了一种交互方式,即“执行程序,展现结果”。
它可以被用作debugging,testing 或者只是执行操作得到一些结果。

NODE的优势

  • 快:基于V8引擎渲染和解析的
  • NODE是单线程基于事件驱动的异步操作
  • NODE提供了无阻塞的I/O操作

I/O:input/output 对文件的增删改查操作

  • JS在客户端浏览器中运行的时候是不能对客户端本地的文件进行I/O操作的,因为我们要保证客户端的安全,JS做为前端开发语言是不可以操作客户端本地文件的,但是浏览器也提供了部分需要用户自主操作的功能,例如:上传图片
  • JS在服务器端NODE环境下运行的时候可以对服务器上的文件进行I/O操作

学习NODE从模块开始

  • 内置模块:自身带的 http、url、fs等
    http:提供HTTP服务器功能
    url:用于解析URL
    fs:操作文件系统
  • 自定义模块:自己写的模块
  • 第三方模块:别人写好的,我们来调取使用
    安装NODE之后自带npm命令,用来管理第三方模块的
    所有我们需要调取的第三方模块都在https://www.npmjs.com/这个网站中

使用npm安装模块
1、安装到全局(global)
npm install xxx(模块名字) -g
npm uninstall xxx -g 卸载已经安装在全局的模块

2、安装在当前的项目下
npm install xxx(模块名字)

npm uninstall xxx 

把模块安装到全局的问题:

  • 以后不管是在哪一个项目目录下,我们都可以"通过使用命令操作的方式"来进行操作了,但是不能通过代码导入这个模块使用
  • 安装在全局有很多时候会导致版本号冲突,例如:我之前安装的是LESS的2.7版本,以前的项目都是使用这个版本开发的,后来LESS升级了,升级到3.1,新版本和之前的版本不太一样,如果全局安装最新的,原来的项目就没办法使用LESS了

把模块安装在当前的项目中也有问题:

  • 不能像安装在全局一样使用命令了,但是可以使用JS导入了
    解决办法:在package.json 文件的scripts这个属性中进行配置
    "scripts": {//->配置NPM脚本命令
    "myFirst": "lessc ceshi.less ceshi.min.css -x"
    }
    以后再DOS中只需要执行npm run myFirst,就可以执行lessc -v这个命令了
  • 在当前的项目中会有一个node_modules文件夹,里面存储的都是我们当前项目所需要使用的模块(这个文件夹很大的,传递给其他人非常的不好处理)
    解决办法:上传gitHub的时候在项目目录中增加一个文件:.gitignore 这个文件中可以配置上传的时候忽略哪些文件,这些被忽略的文件就不在上传了
  • 我们把一些第三方模块安装在A项目下,B项目不能直接的导入使用,如果需要的话还需要在B项目中重新的安装一遍
    解决办法:需要在安装第三方模块的时候,把当前项目的所需要的模块清单写入到package.json的开发依赖项中
    npm install xxx --save-dev 放在开发依赖模块清单中
    npm install xxx --save 放在生产依赖的模块清单中
    下一个B项目如果还是需要这些模块,我们就没有必要一个个的安装了,只需要把package.json文件拷贝到B项目中,然后执行 npm install 即可,这样的系统就会默认按照我们的开发依赖清单一个个的下载 =>"跑环境"

我们平时在做项目开发的时候,首先会在当前项目的根目录下执行:
npm init -y
这样执行完成后,会在当前项目的根目录下生成一个文件:

        package.json       
     {
     "name": "20170222", //->项目名称
     "version": "1.0.0", //->项目的版本号
     "description": "", //->当前项目的描述
     "main": "temp.js", //->当前项目的入口
     "dependencies": {  //->当前项目依赖的第三方模块清单(生产:项目发布上线)
       "less": "^2.7.2"
     },
     "devDependencies": {}, //->当前项目依赖的第三方模块清单(开发:项目正在研发)
     "scripts": {//->命令脚本
     "test": "echo \"Error: no test specified\" && exit 1"
     },
     "keywords": [],
         "author": "",
     "license": "ISC"
     }
  • 模块间的相互调用
    在NODE环境下,它认为每一个JS都可以理解为一个单独的模块,所以我们创建模块只需要创建JS文件即可;并且每一个模块和模块之间是互不干扰的,同时模块之间也可以通过特定方法相互调用一些语句

调用内置模块
require('http')//与导入自定义模块略有不同,参数内不需要有文件路径
require('url')
require('fs')

自定义模块 B模块调用A模块的sum方法:
A.js:
function sum() {...}
module.exports = {//此对象中的方法可为其他模块导入使用
sum: sum
};

    B.js:
    var a = require('./A');//代码导入A模块,可以使用A模块中module.exports中的方法,'./'为导入的模块的路径,表示当前目录,'A为导入模块的名字'
    a.sum();//调用A模块中的sum函数

NODE中的内置模块

服务器端需要处理的事情
+ 在服务器上创建一个服务(监听一个端口)
+ 接收(解析)客户端的请求信息
+ 找到客户端需要的资源文件中的源代码
+ 把源代码返回给客户端

  • HTTP 这个模块主要用于创建服务、监听端口、接收请求、返回内容的管理;

http.createServer([callback]):创建服务,默认遵循的是http传输协议
[callback]:此处的callback并不是当服务创建成功和=后就执行的,而是要等到客户端项向当前的服务发送请求时才会被触发,而且每次发送请求都会被触发,我们需要在这个回调函数中完成:接收解析、资源查找、源代码返回等操作

    客户端如何迪昂当前服务发送请求?

    http://localhost:8080/
    向本地8080端口对应的服务发送请求

    http://本机的ip地址:8080/
    通过服务器的ip地址(外网ip,局域网ip)向当前服务器的8080服务发送请求

    不仅会触发callback,还默认传递了2个参数:function(req.res){}
    - req:request 请求对象,里面有很多属性和方法,存储了客户端的全部请求信息
        + req.url:储存的是客户端请求的资源文件路径以及问号传参的值,如:/css/index.css?name=zxt&age=27(字符串)
    - res:response 响应对象,里面提供了很多方法,可供服务器把源代码返回给客户端
        + res.write([content]);向客户端响应内容(响应的内容是字符串)
        + res.end(); 结束向客户端的响应
        + res.writeHead;重写响应头

listen([port],[callback]):监听端口
[port]:端口号,取值范围0到65535,需要保持端口号的唯一性
[callback]:服务创建成功后,会执行这个回调函数,一般我们会输出一句话提示开发者创建成功
@return:类型,作用
例如
var http = require('http');
var server = http.createServer();
server.listen(80,function () {
console.log('success');
});

  • URL 主要用来解析URL地址的
    url.parse():解析一个完整的url(也可以不完整)的每一项

例如:

    var url = require('url');
    var str = "http://www.zhufengpeixun.cn:80/school/login.html?a=12$b=13#c"
    cosnole.log(url.parse(str,true));

    结果:
    Url {
      protocol: 'http:',
      slashes: true,
      auth: null,
      host: 'www.zhufengpeixun.cn:80',
      port: '80',
      hostname: 'www.zhufengpeixun.cn',
      hash: '#c',
      search: '?a=12&b=13',
      query: { a: '12', b: '13' },//第二个参数true会把问号传参解析成对象
      pathname: '/school/login.html',
      path: '/school/login.html?a=12&b=13',
      href: 'http://www.zhufengpeixun.cn:80/school/login.html?a=12&b=13#c' }
  • FS
    提供一些方法供开发者进行I/O操作

    fs.readFileSync([pathname]):同步读取文件中的内容,读取出的内容是字符串
    fs.readFile([pathname][callback]):异步读取文件的内容
    fs.writeFileSync([pathname],[content]):同步把内容写入到文件中,写入的内容需要是字符串格式,而且写入属于覆盖式写入
    fs.writeFile

静态资源文件请求处理(HTML/CSS/JS/IMG(PNG、JPG、GIF...)/TXT...)

  • 所有的静态资源文件都有一个共同的特征:都有后缀名,后缀名是由字母和数字组成的
  • 分析规律得到,服务器端需要查找文件的路径地址只是在pathname前面加一个点即可
  • 在客户端向我们的服务发送请求的时候,谷歌浏览器会默认请求一个图片"favicon.ico",但是在我们的服务器上是没有这张图片的,所以在使用FS查找内容的时候找不到,导致后台服务报错 =>如果客户端请求的资源文件在服务器上不存在,我们不能终止服务(不能让服务抛异常),只需要返回不存在即可
  • 在IE浏览器中有问题:服务器端返回给客户端的都是字符串格式的数据(不管是HTML/CSS/JS...),对于谷歌浏览器来说,它比较的智能,会自动识别当前代码是什么类型的代码,然后进行解析和渲染;但是IE浏览器比较的弱智,不能识别具体的文件类型,都当成字符串了;
    IE问题解决办法:在返回数据给客户端的时候,指定当前文件的MIME类型,告诉IE是什么类型的即可
    MIME:每一种资源文件都有自己对应的类型,这些类型统称为MIME
    * HTML -> text/html
    * CSS -> text/css
    * JS -> text/javascript
    * PNG -> image/png
    * ...

例:

//->导入需要的内置模块
var http = require('http'),
    url = require('url'),
    fs = require('fs');
    
//->创建服务监听端口
var server = http.createServer(function (req, res) {//创建服务
    var urlObj = url.parse(req.url, true),//url解析,true参数表示将问号传参解析为对象
        pathname = urlObj.pathname,//解析后的请求文件路径
        query = urlObj.query;//解析后的问号传参对象
    //->客户端静态资源文件请求的处理
    var reg = /\.([0-9a-zA-Z]+)/i;
    if (reg.test(pathname)) {
        var conFile = null,
            status = 200;
        try {//容错处理,防止请求文件返回错误报错而阻塞代码执行
        conFile = fs.readFileSync('.' + pathname);
        } catch (e) {
            conFile = 'not found~';
            status = 404;
        }
        //->根据当前请求资源文件的后缀名,计算出文件的MIME类型
        var suffix = reg.exec(pathname)[1].toUpperCase(),//后缀名捕获
        suffixMIME = 'text/plain';//文件MIME类型默认为txt的
        switch (suffix) {
            case 'HTML':
                suffixMIME = 'text/html';
                break;
            case 'CSS':
                suffixMIME = 'text/css';
                break;
            case 'JS':
                suffixMIME = 'text/javascript';
                break;
        }
        //->在返回数据内容之前指定MIME类型(重写响应头)
        res.writeHead(status, {
            'content-type': suffixMIME + ';charset=utf-8;'
        });
        res.end(conFile);
    }
    });
    server.listen(8080);//监听端口

相关文章

网友评论

      本文标题:三、node(一)

      本文链接:https://www.haomeiwen.com/subject/mirgwttx.html