分享

Node服务器

 hdzgx 2019-03-02

一、创建http服务器

  node.js的web程序不用放入web容器中运行,可以自己创建一个http服务器运行程序。需要使用http核心模块。 

复制代码
 1 //创建一个http服务器
 2 const http=require('http');
 3 //创建一个http服务器
 4 const server=http.createServer((req,res)=>{
 5         //设置响应头
 6         res.writeHead(200, {'Content-Type': 'text/html;charset=utf8'});
 7         //通知服务器,所有响应头和响应主体都已被发送
 8         res.end("hello world");
 9 });
10 server.listen('8080',"127.0.0.1",(err)=>{
11     if(err)
12         throw err;
13     console.log("服务器启动成功");
14 })
复制代码

  可以在浏览器通过http://localhost:8080访问服务器。

二、访问服务器上的静态页面  

复制代码
 1 //创建一个http服务器
 2 const http = require('http');
 3 const fs = require('fs');
 4 //创建一个http服务器
 5 const server = http.createServer((req, res) => {
 6     if (req.url == "/yuan") {
 7         //访问页面yuan.html
 8         fs.readFile('./yuan.html', "utf8", (err, data) => {
 9             if (err)
10                 throw err;
11             //设置响应头
12             res.writeHead(200, { 'Content-Type': 'text/html;charset=utf8'});
13             //通知服务器,所有响应头和响应主体都已被发送
14             res.end(data);
15         });
16     } else if (req.url == '/fang') {
17         //访问页面fang.html
18         fs.readFile('./fang.html', "utf8", (err, data) => {
19             if (err)
20                 throw err;
21             //设置响应头
22             res.writeHead(200, { 'Content-Type': 'text/html', 'charset': "utf8" });
23             //通知服务器,所有响应头和响应主体都已被发送
24             res.end(data);
25         });
26     }
27     else if (req.url == "/tupian") {
28         //为图片配置路由
29         fs.readFile('./node.png', (err, data) => {
30             if (err)
31                 throw err;
32             //设置响应头
33             //通知服务器,所有响应头和响应主体都已被发送
34             res.end(data);
35         });
36     }
37     else {
38         //加载含有图片的页面要配置多个路由
39         fs.readFile('./tupian.html', (err, data) => {
40             if (err)
41                 throw err;
42             //设置响应头
43             //通知服务器,所有响应头和响应主体都已被发送
44             res.end(data);
45         });
46     }
47 });
48 server.listen('8080', "127.0.0.1", (err) => {
49     if (err)
50         throw err;
51     console.log("服务器启动成功");
52 })
复制代码

  设置四个简单的路由,获取服务器上的静态页面。

三、闭包和链式调用

  使用下面的代码读取./album文件夹下的所有文件,把其中的文件夹放入dir数组中。然后遍历dir数组。./album下的文件如下:

   

复制代码
 1 const fs = require('fs');
 2 var  dir=[];
 3 fs.readdir('./album',(err,files)=>{
 4     for(var i=0;i<files.length;i++){
 5         var  thefile=files[i];
 6         fs.stat(`./album/${thefile}`,(err,state)=>{       
 7            if(state.isDirectory())
 8                 dir.push(thefile);
 9             console.log(dir);
10         });
11     }
12 })
复制代码

  控制台打印的结果如下:

  

  分析: fs.readdir()的回调函数中定义了变量thefile,回调函数在调用的时候会把变量thefile绑定到相关的对象上。回调函数中又定义了回调函数,所以嵌套的回调函数会把这个对象添加到自己的作用域上。但是fs.readdir()调用时循环会改变thefile的值,所以回调函数的作用域连上的thedfile指向最后一个文件名。  

 fs.stat(`./album/${thefile}`,callback)中我们传入的实参是对应的每一个的文件名。
解决方法1:利用闭包让thefile变量不共享。
复制代码
 1 const fs = require('fs');
 2 var  dir=[];
 3 fs.readdir('./album',(err,files)=>{
 4     for(var i=0;i<files.length;i++){
 5         var  thefile=files[i];
 6         (function (f){
 7             fs.stat(`./album/${f}`,(err,state)=>{       
 8                 if(state.isDirectory())
 9                      dir.push(f);
10                      console.log(dir);
11              });
12         }(thefile))     
13     }
14 })
复制代码

  

  解决方法2:每次只让事件队列中有一个fs.stat()函数在执行。 

复制代码
 1 const fs = require('fs');
 2 var  dir=[];
 3 fs.readdir('./album',(err,files)=>{
 4         (function itera(f){
 5             //结束递归
 6             if(f===files.length){
 7                 console.log(dir);
 8                 return;
 9             }            
10             fs.stat(`./album/${files[f]}`,(err,state)=>{       
11                 if(state.isDirectory())
12                      dir.push(files[f]);
13                      console.l
14                      og(`./album/${files[f]}`);
15                    itera(++f);
16              });
17         }(0))     
18 })
复制代码

  

五、自己实现静态服务  

复制代码
 1 //用node提供静态服务
 2 const http = require('http');
 3 const fs = require('fs');
 4 const url = require('url');
 5 const path = require('path');
 6 const server = http.createServer((req, res) => {
 7     //获取要访问的文件路径
 8     let requrl = url.parse(req.url).pathname;
 9     //拼合成绝对路径
10     let dirpath = path.join(__dirname, 'static', requrl);
11     //读取当前路径下的文件
12     fs.readFile(dirpath, (err, data) => {
13         //当前文件不存在
14         if (err) {
15             let p404 = path.join(__dirname, 'static/404.html');
16             fs.readFile(p404, (err, data) => {
17                 if (err)
18                     throw err;
19                 res.writeHead(404, { 'Content-Type': `text/html;charset=utf8` });
20                 res.end(data)
21             });
22             return;
23         }
24         //文件存在
25         //获取文件的后缀名
26         let ext = path.extname(requrl);
27         //异步的方式获取响应头
28         getMime(ext, (mime) => {
29             res.writeHead(200, { 'Content-Type': `${mime};charset=utf8` });
30             res.end(data);
31         });
32     });
33 });
34 server.listen('8080', 'localhost', (err) => {
35     if (err)
36         throw err;
37     console.log("服务器成功启动!");
38 });
39 //根据文件的类型给出对应的mime类型
40 function getMime(extname, callback) {
41     let file = path.join(__dirname, 'mime.json');
42     fs.readFile(file, (err, data) => {
43         if (err)
44             throw err;
45         data = JSON.parse(data);
46         let mime = data[extname] || "text/plain";
47         callback(mime);
48     })
49 }
复制代码

当服务器启动时,放在static文件下的问价可以被直接访问。

六、post请求和get请求 

复制代码
 1 //post请求
 2 const http = require('http');
 3 const fs = require('fs');
 4 const querystring=require('querystring');
 5 http.createServer((req, res) => {
    //读取服务器上的静态页面 6 if (req.url == '/') { 7 fs.readFile('./form.html', (err, data) => { 8 if (err) 9 throw err; 10 res.writeHead(200, { 'Content-Type': `text/html;charset=utf8` }); 11 res.end(data); 12 }) 13 }
    //接受post请求 14 else if (req.url = "/dopost" && req.method.toLocaleLowerCase() == 'post') { 15 let data = ''; 16 req.addListener('data', (chunk) => { 17 data += chunk; 18 }); 19 req.addListener('end', () => {
          //打印接受的数据 20 console.log(data);
          //将数据转换成字符串 21 let dataObj=querystring.parse(data); 22 console.log(dataObj.user); 23 }) 24 res.writeHead(200, { 'Content-Type': `text/html;charset=utf8` }); 25 res.end('success'); 26 } 27 else { 28 res.writeHead(200, { 'Content-Type': `text/html;charset=utf8` }); 29 res.end('404'); 30 } 31 }).listen('8080', 'localhost');
复制代码

 

复制代码
 1 //get请求
 2 const  http=require('http');
 3 const  url=require('url');
 4 //创建一个服务器
 5 http.createServer((req,res)=>{
 6         //解析接受到url
 7         //输入http://localhost:8080/lijunjie.hml?name=123
 8         let urlObj=url.parse(req.url);
 9         //输出name=123
10         console.log(urlObj.query);
11         res.end('请求成功');
12 }).listen(8080,'localhost');
复制代码

七、ejs模板引擎

  

  首先需要通过npm安装ejs模块。创建index.ejs文件。  

复制代码
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 
 4 <head>
 5     <meta charset="UTF-8">
 6     <title>Document</title>
 7 </head>
 8 
 9 <body>
10     <p> 我买了一个小米
11         <%=a%>
12     </p>
13     <% for(var i=0;i<news.length;i++){%>
14         <li>
15             <%=news[i]%>
16         </li>
17         <%}%>
18 </body>
复制代码

bind.js文件  

复制代码
 1 //创建一个http服务器
 2 const http = require('http');
 3 const fs = require('fs');
 4 const ejs=require('ejs');
 5 //创建一个http服务器
 6 const server = http.createServer((req, res) => {
 7     //读取模板
 8     fs.readFile('./index.ejs', (err, data) => {
 9         //接受模板
10         let template = data.toString();
11         //数据
12         let datas = { a: 3, news: ['adsada', 'xiaomi'] };
13         let html=ejs.render(template,datas);
14         res.end(html);
15     })
16 
17 });
18 server.listen('8080', "127.0.0.1", (err) => {
19     if (err)
20         throw err;
21     console.log("服务器启动成功");
22 })
复制代码

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约