Node.js学习第一天笔记

1 服务器创建

  • 创建服务器
    • 利用require引入http模块:var http=require("http")
    • 利用http模块创建server服务器;
      • 创建服务器:var server=http.createServer(function(req,res){})
      • req:为形参,指的是前端向后台发送的请求;
      • res:为形参,指的是后台向前端响应的结果;
  • 服务器监听端口号的设置
    • 通过listen监听端口号:server.listen(8080),端口号可以自定义设置;
  • 浏览器发送请求
    • 在网址栏中设置localhost:8080,加载页面;发送请求,每刷新一次,请求一次;端口号必须与设置的一致;
    • 网址栏中的地址可以是本地IP加端口号;访问页面;
  • 服务器的运行
    • 利用webstorm中右键中的run,在里面运行服务器;
    • 可以在文件夹中利用命令行node 01http-server.js,开启服务器;ctrl+c关闭服务器;

2 服务器中的知识

  • const:定义不变的常量;
  • require引入模块:const http=require("http");
  • req.url:指请求的地址;
  • console.log("这是打印的内容");:指在服务器中打印显示的内容;不在页面的console中显示;
  • res.writeHeader(200,{"Content-Type":"text/html;charset=utf-8"});:指通过writeHeader来设置后台响应的状态码和需要渲染的文件类型及字符集编码;
    • 200:为状态码;
    • content-type:指的是响应的类型;
      • html页面:text/html;加上字符集编码格式,否则会出现乱码;
      • css文件:text/css;
      • JS文件:application/javascript;
      • 图片:image/png或image/x-icon;
  • res.write("这是页面呈现的内容");指在页面上显示的内容;
  • res.end():指的是响应结束,不然在页面中会持续加载;
  • 服务器内容在修改之后,必须重新启动服务器;
  • 注意:chrome浏览器在页面发送一次请求后,会响应两次,其中包含默认响应一次/favicon.ico小图标的响应;所以需要对其进行判断,阻止其响应;
    • 利用req.url来判断请求地址,进行条件判断;小图标的请求地址为/favicon.ico;
     if(req.url==="/favicon.ico"){
         return;//阻止程序执行;
      }
    
  • 基本的http-server服务器的创建代码
     //创建服务器,http模块的运用;
      const http=require("http");
      const server=http.createServer(function (req,res) {
          //request:前端向后台发起请求;请求页面和数据等;
          //response:后台给前端响应;
          if(req.url==="/favicon.ico"){
              return;//阻止程序执行;
          }
          console.log("这是打印的内容");
          //通过writeHeader来设置后台响应的状态码和需要渲染的文件类型及字符集编码;
          res.writeHeader("200",{"Content-Type":"text/html;charset=utf-8"});
          res.write("这是页面呈现的内容");
          res.end();//响应结束
      
      });
      //端口号监听
      server.listen(8080);
    

3 文件系统fs(file System)模块

  • 引入fs模块
    • 代码:const fs=require("fs")

3.1 读取文件

  • 代码:fs.readFile(path,callback)
    • path:文件路径;
    • callback:回调函数;
      • 代码:function(err,data){}
      • err:指路径错误时,执行的代码;if(err){ res.end("404") }
      • data:指路径下的文件中的数据内容;
        • 在浏览器中通过设置字符集编码来呈现数据原来的内容;
        • 在服务器中打印的data数据,为buffer文件,即数据转化为二进制的代码串;通过data.toString()可以拿到正常的数据内容;
  • 路径
    • 定义:指的是在端口后面的部分,自身包含斜杠;
    • 如网址地址localhost:8080/1.txt,里面的请求路径为/1.txt;通过req.url获取;
    • 在服务器中定义变量pathname,设置不同的路径;var pathname="./static"+req.url;
    • 当浏览器请求不同的路径时,服务器就会根据不同的路径读取不同的数据,然后响应不同的数据;
  • 知识点:
    • 创建服务器后,首先要先处理chrome浏览器中小图标icon自动响应的问题;
    • 路径变量的创建;
    • 代码res.end("404")为二合一的写法;指的是res.write("404")res.end()的组合写法;
    • 响应的数据在服务器中打印的内容为buffer,是二进制的编码;在浏览器中的数据为乱码,需要设置字符集编码;在服务器中打印data内容为实际的内容,不是buffer文件,则使用toString()方法;即代码:console.log(data.toString());
  • 注意:
    • node.js不会自动根据路由的不同,渲染不同的内容,它需要我们自己去判断路径的不同,来手动返回不同的内容;
    • 如果不想反复重启服务器,而又想输入不同内容,渲染不容页面的话,可以使用读取文件和处理路径的方式来解决;即设置变量pathname;
  • 读取文件步骤
    • 前端浏览器向服务器发送请求;
    • 服务器接到请求后,去磁盘中读取文件;
    • 把读到的该文件返回给前台;
  • 代码:
     const http=require("http");
     const fs=require("fs");//文件系统模块
     //创建服务器
     const server=http.createServer(function (req,res) {
         //处理icon自动响应的问题;
         if(req.url==="/favicon.ico"){
             return;
         }
         //根据路径不同,返回不同的文件;路径为地址中端口号后面的部分;路径地址中带斜杠;
         var pathname="./static"+req.url;//其中req.url里面是带斜杠的
         //fs.readFile读取文件
         fs.readFile(pathname,function (err,data) {
             if(err){
                 res.end("404");//二合一:res.write("404")和res.end()的组合;
             }
             //设置响应数据在浏览器中的渲染类型和字符集编码
             res.writeHeader(200,{"Content-Type":"text/html;charset=UTF-8"});
             res.end(data);
             console.log(data);//在服务器中打印data数据,为buffer文件,即二进制的一串代码;不同的数据对应不同的二进制代码;
             //打印的数据:
         })
     });
     //监听
     server.listen(8080);
    

3.2 写入文件

  • 代码格式:fs.writeFile(path,data,callback);
    • path:为修改的文件的路径;
    • data:修改的数据内容,可以是字符串;
    • callback:回调函数,只有一个形参为err;
    • 代码:
     const http=require("http");
     const fs=require("fs");
     const server=http.createServer((req,res)=>{
         fs.writeFile("./static/2.txt","111这是写入的文件",(err)=>{
             if(err){
                 res.end("404");
             }
             res.end();
         })
     });
     server.listen(8080);
    

3.3 获取文件夹下的所有文件,并筛选

  • 思路:
    • 创建server服务器
    • 通过代码fs.readdir(path,(err,files)=>{});来读取文件夹内容;其中files为文件下所有文件内容组成的数组;
    • 遍历数组,分别判断每个文件的类型;
      • 使用代码fs.stat(path,(err,stats)=>{});来判断每个文件的类型;path为文件地址;
      • 使用代码:stats.isDirectory(),判断是否为文件夹,如果是文件夹,返回true,反之,返回false;
    • 新建空数组,将符合条件的文件夹插入到数组中;
  • 知识:
    • 地址路径的拼接:"./"+files[i],其中files[i]为文件名称,为字符串,通过字符串拼接建成新的路径字符串;
    • 代码stats.isFile()指的是判断文件时候为纯文件,如果为文件夹,返回false,其他文件返回true;
  • 问题:
    • 获得files数组后,遍历数组时会出现两个问题;
      • 利用for循环时,i值会出错,由于fs.stat()为异步,函数中获取的i值为最大值;会出错;
        • 解决方法:利用闭包或let创建变量;或不是用for循环,使用迭代函数递归;
      • 获取最终的ary数组时,会出现同异步问题;直接打印ary获取的是空数组;同步优先执行;
        • 解决方法:将获取数据ary放在异步的函数中,通过判断i值,来判断遍历结束;获取最终的ary数组;
  • 注意:
    • 利用for循环遍历数组时,要注意,for循环中是先判断条件,然后再执行语句,所以在语句执行中i的最大值为数组长度减一;不会等于数组长度;所以最终判断i值是否为数组长度减一,来判断数组遍历完;经测试后发现if(stats.isDirectory()){ary.push(files[i]);}此行代码执行为同步执行;所以需要将判断条件放在其后面,这样才能先执行上面代码,再判断下面条件,停止运行;
      • 如果在for循环中,条件判断中,存在异步操作,可以将i<=ary.length,然后再判断i是否等于ary.length,如果等于就直接return阻止程序执行;条件判断放在最开始;这样就可以解决,在i==ary.length-1时,同步先执行,异步后执行的问题;
    • 利用迭代函数递归执行自己,然后通过在开始判断i的值,来进行输出数据并阻断;相当于将异步运行转化为同步运行;
  • 代码:
     //需求:获取dady1下的所有文件,筛选其中的文件夹放入数组中;
     const http=require("http");
     const fs=require("fs");
     //创建服务器
     const server=http.createServer((req,res)=>{
         if(req.url==="/favicon.ico"){
             return;
         }
         //读取dady1的文件夹下的所有文件;
         fs.readdir("./",(err,files)=>{
             //files获取是一个数组,数组元素为文件夹下的文件;
             //判断数组中各元素是否为文件夹,获取其中的文件夹插入到新的数组中;
             var ary=[];
             //1.通过for循环遍历数组,里面的异步运行里面的i值为错值,而且ary打印为空数组,同步先运行;
             /*var ary=[];
             for(var i=0; i{
                     if(stats.isDirectory()){
                         ary.push(files[i]);//此时的i值会出错;为最大值10;
                     }
                 })
             }
             console.log(ary);//此时打印出来的为空数组;由于其为同步,先执行;*/
             //2.1利用let定义变量,来解决i值问题;将打印ary放在异步中,解决ary的同步问题;
             /*for(let i=0; i{
                     if(stats.isDirectory()){//将测试得出,此判断为同步
                         ary.push(files[i]);
                     }
                     if(i===files.length-1){
                         console.log(ary);
                         return;
                     }
                 });
             }*/
             //2.2利用闭包解决i值问题
             /*for(var i=0; i{
                         if(stats.isDirectory()){//将测试得出,此判断为同步
                             ary.push(files[i]);
                         }
                         if(i===files.length-1){
                             console.log(ary);
                             return;
                         }
                     });
                 })(i);
             }*/
             //3 利用闭包和递归函数
             //利用闭包函数执行,利用迭代函数解决数组遍历问题;将迭代函数放在异步中,相当于变成同步,待异步执行完后,在执行下一步;
             (function Iterator(i) {
                 if(i===files.length){
                     console.log(ary);
                     return;
                 }
                 fs.stat("./"+files[i],(err,stats)=>{
                     if(stats.isDirectory()){
                         ary.push(files[i]);
                     }
                     //利用递归函数,迭代函数执行
                     Iterator(++i);//执行自己;
                 })
             })(0)
         });
         res.end();
     });
     //监听服务器
     server.listen(8080);
    

4 前台向后台发送请求的形式

  • form表单提交:
    • action:服务器;设置协议和主机名和端口号;如:http://localhost:8080;
    • method:请求方式;
    • submit:提交按钮;
    • name:指的是input中的name设置,必须设置,在网址中作为参数传递,其值为key的值;
    • value:指的是input中的value设置,可以不设置,设置value后,文本框中就默认填入文件,如果不设置,文本框内输入的内容就作为value值来上传,在网址中作为参数传递,其值为value的值;
    • 最终发送请求后的地址:http://localhost:8080/?userr=dd&passs=3333;
    • 代码:
     
     
     
         
         表单提交请求形式
     
     
     
  • ajax:
    • {url:"xxx",type:"get/post",dataType:"json",data:"参数",fnLoading:fn,fnComplete:fn,success:fn(data){},error:function(){},timeout:300}
    • 1)jQuery中ajax提交请求代码:
     
     
     
         
         jQuery中ajax提交请求
     
     
     
     
     
     
    
    • 2)自己封装的ajax库提交请求代码:
     
     
     
         
         自己封装的ajax提交请求
     
     
     
     
     
     
    
  • jsonp:三步走
    • 1)创建一个有名字的全局函数;
    • 2)通过script发送请求;
    • 3)在函数中接受别人调用你全局函数传来的数据;
    • 发送请求html代码:
     
     
     
         
         jsonp提交请求
     
     
     
     
     
     
    
  • 以上三种形式下,服务器的创建代码
    • 代码:
     const http=require("http");
     const url=require("url");
     http.createServer((req,res)=>{
         if(req.url==="/favicon.ico") return;
         console.log(req.url);
         var obj=url.parse(req.url,true);//不添加true,则query属性值为字符串;添加第二个参数后,query属性值为对象;
         var que=obj.query;
         console.log(que);//此时为对象;
         res.end("ok");
     }).listen(8080);
    

5 发送请求的方式

  • 后台不在乎前端用什么来请求数据,后台在乎的是前端的请求方式method;
  • 常见的请求方式:
    • get:用来取数据;
    • post:用来提交数据;

5.1 get数据请求方式

  • get数据的获取:
    • get通过浏览器的地址栏来传输数据;
    • get参数:req.url得到的是端口号后面的部分,包含斜线;如:/?userr=dd&passs=3333
    • 接收get参数的方式有三种:
      1)纯手工开发-split切req.url字符串,然后数组遍历形成对象;
      2)querystring模块:把一个 URL 查询字符串 str 解析成一个键值对的对象;
      • 代码:querystring.parse("k1=v1&k2=v2");
        3)url模块;
      • url对象:url.parse(req.url);打印出来为一个对象;里面有许多属性和属性值;
       Url {
         protocol: null,//协议;http
         slashes: null,//斜杠
         auth: null,
         host: null,//主机,包括主机名加端口号
         port: null,//端口号
         hostname: null,//主机名
         hash: null,//哈希值
         search: '?userr=dd&passs=3333',//问号之后的部分不包括hash
         query: 'userr=dd&passs=3333',//参数
         pathname: '/',//问号前的部分,带斜线
         path: '/?userr=dd&passs=3333',//路径
         href: '/?userr=dd&passs=3333' }//所有的地址;
      
      • query属性:默认情况下属性值为字符串;在url.parse(req.url,true)代码中,添加第二个参数为true;则 query属性总会通过 querystring 模块的 parse()方法生成一个对象。如果为 false,则返回的 URL 对象上的query属性会是一个未解析、未解码的字符串。默认为 false。
    • 接收get参数的三种方式代码:
     const http=require("http");
     const querystring=require("querystring");
     const url=require("url");
     http.createServer((req,res)=>{
         if(req.url==="/favicon.ico") return;
         //req.url打印为:/?userr=dd&passs=2222
         //方案1:原始的字符串切成数组,数组遍历形成对象;
         var obj={};
         var strQuery=req.url.split("?")[1];
         var ary1=strQuery.split("&");
         for(var i=0; i

6 cmd中命令行指令

  • 查看node.js的版本命令:node -vnode --version;
  • ls:列出当前文件夹下的所有文件;
  • node+文件:运行该文件;node 01http-server.js:运行服务器;
  • tab键:用来补全内容;
  • ctrl+c:阻断程序执行,即关闭服务器;
  • clear: 清空内容;
  • touch:创建文件;可以创建任何文件;
  • mkdir:创建文件夹,创建多个文件夹,中间用空格连接;如:mkdir aa bb,即创建aa和bb两个文件夹;
  • node:只输入node指令后,会进入一个repl的环境,是JS在服务器端运行的环境;指的是:read(读取) eval(执行) print(打印) loop(循环);
  • cd+文件名:打开本文件夹下的该文件;
  • cd ../:回到父级目录;
  • rm -rf xxx:删除xxx文件;

7 其他知识

  • 前端工程师:JS文件在浏览器中运行;
  • 后台工程师:JS文件在服务器中运行;
  • 网址的部分解读;


    Node.js学习第一天笔记_第1张图片
    网址解读
    • protocal:协议;设置或返回当前URL的协议;
    • host:主机;设置或返回主机名和当前URL端口号;
      • hostname:主机名;设置或返回主机名;
      • port:端口号;设置或返回端口号;
    • pathname:路线;设置或返回当前URL的路径;包含斜杠
    • search:设置或返回从问号开始的URL部分;包含问号,不包括哈希值;
    • hash:哈希值;设置或返回从#号开始的URL部分;
    • href:设置或返回完整的URL部分;

你可能感兴趣的:(Node.js学习第一天笔记)