1 服务器创建
- 创建服务器
- 利用require引入http模块:
var http=require("http")
- 利用http模块创建server服务器;
- 创建服务器:
var server=http.createServer(function(req,res){})
; - req:为形参,指的是前端向后台发送的请求;
- res:为形参,指的是后台向前端响应的结果;
- 创建服务器:
- 利用require引入http模块:
- 服务器监听端口号的设置
- 通过listen监听端口号:
server.listen(8080)
,端口号可以自定义设置;
- 通过listen监听端口号:
- 浏览器发送请求
- 在网址栏中设置
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循环时,i值会出错,由于fs.stat()为异步,函数中获取的i值为最大值;会出错;
- 获得files数组后,遍历数组时会出现两个问题;
- 注意:
- 利用for循环遍历数组时,要注意,for循环中是先判断条件,然后再执行语句,所以在语句执行中i的最大值为数组长度减一;不会等于数组长度;所以最终判断i值是否为数组长度减一,来判断数组遍历完;经测试后发现
if(stats.isDirectory()){ary.push(files[i]);}
此行代码执行为同步执行;所以需要将判断条件放在其后面,这样才能先执行上面代码,再判断下面条件,停止运行;- 如果在for循环中,条件判断中,存在异步操作,可以将
i<=ary.length
,然后再判断i是否等于ary.length,如果等于就直接return阻止程序执行;条件判断放在最开始;这样就可以解决,在i==ary.length-1
时,同步先执行,异步后执行的问题;
- 如果在for循环中,条件判断中,存在异步操作,可以将
- 利用迭代函数递归执行自己,然后通过在开始判断i的值,来进行输出数据并阻断;相当于将异步运行转化为同步运行;
- 利用for循环遍历数组时,要注意,for循环中是先判断条件,然后再执行语句,所以在语句执行中i的最大值为数组长度减一;不会等于数组长度;所以最终判断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
; - 代码:
表单提交请求形式 - action:服务器;设置协议和主机名和端口号;如:
- 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 -v
或node --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文件在服务器中运行;
-
网址的部分解读;
- protocal:协议;设置或返回当前URL的协议;
- host:主机;设置或返回主机名和当前URL端口号;
- hostname:主机名;设置或返回主机名;
- port:端口号;设置或返回端口号;
- pathname:路线;设置或返回当前URL的路径;包含斜杠
- search:设置或返回从问号开始的URL部分;包含问号,不包括哈希值;
- hash:哈希值;设置或返回从#号开始的URL部分;
- href:设置或返回完整的URL部分;