1、Web 与 Node.js 相关技术介绍

1.1、Web应用的基本组件

  web应用的三大部分

  brower(GUI)<==>webserver(business logic、data access)<==>database(data storage)

  GUI(浏览器、HTTP客户端)

  Web服务器(Node.js service)

    请求(浏览器访问网页时发送一个请求给服务器)

    业务逻辑(服务器进行处理请求)

    连接数据库(处理的过程中需要连接数据库,进行数据处理,最后将数据返回给GUI也就是浏览器,这是一个请求响应的过程)

  数据库(SQLite,LevelDB,Redis)

  GET  /yorkie HTTP/1.1

  Host:github.com

  Connection:keep-alive

  Accept:text/html,application/xhtml

  User-Agent:My iPhone

  Accept-Encoding:gzip,deflate,sdch

  (请求的方法(method))get就是个请求请求的方法有很多种,主要有get和post两种,其他还有很多

  /yorkie这部分就是请求的路径,也是一个资源的定位

  1.1这一部分标识使用的HTTP的版本

  Host:github.com这一部分表示我们要访问的域名,访问域名最后就可以转化成一个url了

  

1.2、expressjs框架

  npm install express -g(全局安装成功,不带-g出现错误提示)

  安装成功之后这时桌面(安装完会提示安装到哪了,具体看下图:)会出现node_moudules这么一个文件夹

[lin@vultr ~]$ sudo npm install express -g
/usr/lib
└─┬ express@4.16.
├─┬ accepts@1.3.
│ ├─┬ mime-types@2.1.
│ │ └── mime-db@1.37.
│ └── negotiator@0.6.
├── array-flatten@1.1.
├─┬ body-parser@1.18.
│ ├── bytes@3.0.
│ ├─┬ http-errors@1.6.
│ │ └── inherits@2.0.
│ ├─┬ iconv-lite@0.4.
│ │ └── safer-buffer@2.1.
│ └── raw-body@2.3.
├── content-disposition@0.5.
├── content-type@1.0.
├── cookie@0.3.
├── cookie-signature@1.0.
├─┬ debug@2.6.
│ └── ms@2.0.
├── depd@1.1.
├── encodeurl@1.0.
├── escape-html@1.0.
├── etag@1.8.
├─┬ finalhandler@1.1.
│ └── unpipe@1.0.
├── fresh@0.5.
├── merge-descriptors@1.0.
├── methods@1.1.
├─┬ on-finished@2.3.
│ └── ee-first@1.1.
├── parseurl@1.3.
├── path-to-regexp@0.1.
├─┬ proxy-addr@2.0.
│ ├── forwarded@0.1.
│ └── ipaddr.js@1.8.
├── qs@6.5.
├── range-parser@1.2.
├── safe-buffer@5.1.
├─┬ send@0.16.
│ ├── destroy@1.0.
│ └── mime@1.4.
├── serve-static@1.13.
├── setprototypeof@1.1.
├── statuses@1.4.
├─┬ type-is@1.6.
│ └── media-typer@0.3.
├── utils-merge@1.0.
└── vary@1.1.

在网络服务器上的

  

本地安装:
npm install xxx 安装到命令行所在目录的node_module目录。
全局安装:
npm install xxx -g 安装到 \AppData\Roaming\npm\node_modules目录。

下面一段代码简单实现在浏览器页面显示一部分内容:

var express = require('express');
var app = express(); app.get('/jikexueyuan',function(req,res){
res.send('hello jikexueyuan');
}); app.listen(3000);

以下是在浏览器中显示的内容。  

注意查看expressJS官方API文档的侧边栏的基本组件

2、expressjs 的配置与路由

2.1、expressjs基础

  请求和响应的数据全部放在头部是不现实的。

  get一般是从服务器拿数据,是没有{body}这种东西的

  

//or cristring style

name=hahaha

name=hahaha&foo=bar&x[y]=10
{
name:'hahaha',
foo:'bar',
x: { y: 10}
} //expressjs request_object = {
method:&apos;POST&apos;,
path: &apos;/hahahaha&apos;,
headers:{
&apos;Content-Type&apos;:&apos;application/json&apos;,
...
...
}
body:{}
} request.body = JSON.parse(rawBody);
bodyparser.urlEncoded(); //response HTTP/1.1 200 OK
...
..
... //express
status var response = {}
response.status = function (){};
response.status(200);
response.status(500); response.headers['Content-Type'] = 'application/json';
response.set('Content-Type', 'application/json'); response.send([20]);
response.json()

 

比较重要的点:

  req.path

  req.hostname(主机名)

  req.body

  bodyParser(模组:用处:用来解析BODY的,因为body有很多编码方式(像json、cristring等等)express自己是不会自己进行解析的,bodyParser提供了两种方式

  request.body = JSON.parse(rawBody);

  bodyparser.urlEncoded();

2.2、expressjs的初始化配置

request

|

middleware 1

|

middleware 2

|

middleware 2

|

URL

|

response

  middleware: (中间件----由很多回调函数组成的东西)

    app.use

    app.get

    app.post

  request:

    req.params

    req.query

    req.body

  response:

    res.send()

    next()

2.3、expressjs的路由

2.4、expressjs的返回响应

app = express()

app.use

  body-parser:https://github.com/expressjs/body-parser

res.send()

  plain text

  JSON

代码示例:

var express = require('express');
var app = express(); app.get('/plain-text', function(req, res){
res.status(200).send('<h1>'+"hello"+`world<h1>`);
}); app.get('/category', function(req, res){
res.status(200);
res.json({
python: 20,
nodejs: 1,
others: 10
});
}); var questions = [
{
id:1,
title: 't1',
asker: 'you',
course: 'nodejs',
'last-reply': Date.now(),
reply:1,
state: 'resolved'
},
{
id:2,
title: 't2',
asker: 'you',
course: 'nodejs',
'last-reply': Date.now(),
reply: 1,
state: 'unresolved'
},
{
id:3,
title: 't3',
asker: 'you',
course: 'nodejs',
'last-reply': Date.now(),
reply: 1,
state: 'unresolved'
},
{
id:4,
title: 't4',
asker: 'you',
course: 'nodejs',
'last-reply': Date.now(),
reply: 1,
state: 'unresolved'
}
]; app.get('/questions', function(req, res){
res.status(200);
res.json(questions);
}); //liebiao guolv (jia ru yi ge state) app.get('/questions/all', function(req, res){
res.status(200);
res.json(questions);
}); app.get('/questions/unresolved', function(req, res){
res.status(200);
res.json(questions.filter(function(q){
//console.log("q : "+ q);
//console.log("q.state : " + q.state );
//console.log("q && q.state: " + (q && q.state));
var ppp = q && q.state;
//console.log(ppp);//resolved unresolved unresolved unresolved
//if(q.state === 'unresolved')return q; //This is the same function!!!
if(q.state ==='unresolved')return true;//This is the real function !!!
//return q && q.state === 'unresolved';
}));
}); app.get('/questions/resolved', function(req, res){
res.status(200);
res.json(questions.filter(function(q){
return q && q.state === 'resolved';
}));
}); app.listen(3000);

3、expressjs 与HTML

3.1、使用expressjs返回HTML内容

HTML

  Content-Type:text/html(服务器要返回给客户端什么类型的数据)

  fs.createReadStream('xxx.html').pipe(res)

  res.render()

3.2、模板渲染

模板:

  用途:复用HTML组件,简化开发流程

  比喻:模具

渲染/生成:

  用途:“生成”最终的HTML内容

  比喻:烤饼干

3.3、使用app.set来设置express实例所使用的模板引擎

ejs:http://ejs.co(模板引擎)

使用模板引擎,需要加一个语句(想用其他的模板引擎的话,直接修改ejs这一部分)

app.set('view engine', 'ejs')
res.render('home.ejs', {title: 'ejs template'})

这里出现了cannot find module 'ejs' 的问题,解决办法是在用户目录下执行以下两行命令

npm install ejs -g  (全局安装ejs)(发现全局安装ejs之后并不起作用(这里是我忘了这是普通用户的原因了。)之后再执行下面一行命令)
              (全局安装就是必须用root权限安装,不是root用户就用sudo ,是root就直接使用以上命令安装) npm install ejs  (在代码目录下再安装一次) 安装完成功之后的情况下可以移动当前所在目录的项目了,具体原因未知。不过对我来说,可以用就行了!

render_myprogram2.js

var express = require('express');
var app = express(); app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');
/*定义views的路径*/
/*__dirname好像是个全局变量,注意这里是两个下划线*/
app.get('/', function(req, res){
res.render('home.ejs', {name: 'nameishahaha'});
}); app.listen(3000);

home.ejs(views目录下的home.ejs)

<html>
<head>
<title>new template</title>
</head>
<body>
<p> hello hahahahahaha </p>
<p> Hi <%= name %> </p>
</body>
</html>

如何与request对象进行结合:

render_myprogram.js

var express = require('express');
var app = express(); app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');
/*定义views的路径*/
/*__dirname好像是个全局变量,注意这里是两个下划线*/
app.get('/', function(req, res){
res.render('home.ejs', {name: 'nameishahaha'});
}); app.get('/request/:id', function(req, res){
var locals = {name: 'gagagagaga', 'id': req.params['id']};
res.render('home.ejs', locals);
}); app.listen(3000);

home.ejs(views目录下的home.ejs)

<html>
<head>
<title>new template</title>
</head>
<body>
<p> hello hahahahahaha </p>
<p> Hi <%= name %> </p>
<p> id <%= id %> </p>
</body>
</html>

3.4、前后端共用模板

在前端渲染(render)模板

<script srv="ejs.js"></script>
ejs.render(tmpl,data)

复制文件ejs.min.js到根目录下的headers文件夹下

这里老师讲的main文件没有引入,不知道原因是什么他运行着没有问题,但是我还是自己引入了main1.js

下面是代码

render_my_program2.js

var express = require('/usr/lib/node_modules/express');
//这里是真的屌,原来这里的参数是express框架的目录,恕我愚钝
//所以这里可以通过在项目目录执行npm install express来解决呢
var app = express(); app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');
/*定义views的路径*/
/*__dirname好像是个全局变量,注意这里是两个下划线*/ app.use(express.static(__dirname));
//console.log(__dirname);// /home/lin/lin_nodejs_nodes/my_project1 app.get('/', function(req, res){
res.render('home.ejs', {name: 'nameishahaha'});
}); app.get('/request/:id', function(req, res){
var locals = {name: 'gagagagaga', 'id': req.params['id']};
res.render('home.ejs', locals);
}); app.listen(3000);

/views/home.ejs

<html>
<head>
<title>new template</title>
</head>
<body>
<p> hello hahahahahaha </p>
<p> Hi <%= name %> </p>
<p> id <%= id %> </p>
<input id="new-temp-val" type="text">
<div id="new-temp"></div>
</body> <script type="text/javascript" src="/ejs.min.js"></script>
<!--这里的/ejs.min.js是__dirname/ejs.min.js-->
<script type="text/javascript">
//alert("test_alert"); var tmpl = '<p>A new template</p>';
var newTempDiv = document.getElementById('new-temp'); /* setTimeout(function(){
newTempDiv.innerHTML = ejs.render(tmpl);
},2000);
*/ //因为后面有了main.js所以这里的js代码不管用了,就注释掉可以了
</script>
<script type="text/javascript" src="/main_js_dir/main1.js"></script>
<!--/指的是当前项目的工作路径的根目录,我没写/的时候报错了。-->
</html>

/main_js_dir/main1.js

//alert("test_alert");//alert好像在只有声明了是text/javasceipt类型才会管用,在这里不管用
console.log("????");
var newTemp = document.getElementById('new-temp'); setInterval(function(){
var tmpl = '<p>the value is <%= val1 %></p>';
val1 = document.getElementById('new-temp-val').value || null;
newTemp.innerHTML = ejs.render(tmpl);
},2000);

4、模组化

1、如何设计API

  不要让用户使用关键字new

  保持简洁

  不要轻易地输出接口

2、发布到NPM

  npm publish

  生成一个package.json文件,在生成的时候他会自动地把你的一些内容给输入进去,包括你之前有node modules他会自动识别node modules里面的模组,然后将他们包含在你的package里面,这样你在别人从npm装上你的包的时候就能自动安装这些dependencys(依赖),这样比较方便的,所以npm init是比较方便的东西,等你准备发布之后,你可使用npm publish将你的包上传到npm的服务器上,然后在另外一台机器上你就可以用npm install +你的名字然后就可以将你相应的包下载到对应的node modules目录下

3、课程总结

  express或Node.js在开发Web应用程序的基本流程

  如何在Node.js中复用代码并使用npm来分发

前端(Node.js)(3)-- Node.js实战项目开发:“技术问答”的更多相关文章

  1. Android快乐贪吃蛇游戏实战项目开发教程-01项目概述与目录

    一.项目简介 贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏. 我已经将做好的案例上传到了应用宝,无病毒.无广告,大家可以放心下载下来把玩一下.应用宝 ...

  2. Vue 实战项目开发流程

    一 基础配备 ## 一.环境搭建 #### 1.安装node - 去[官网](https://nodejs.org/zh-cn/)下载node安装包 - 傻瓜式安装 - 万一安装后终端没有node环境 ...

  3. 嵌入式C实战项目开发技巧:如果对一个有规律的数组表进行位移操作

    在嵌入式项目开发中,LED灯的操作是一定要会的,也是基础中的基础,比如用51单片机写个跑马灯,这不简单嘛,定义一个数组把那8个跑马灯存起来,然后搞个for循环不就可以了嘛,但是,实际工作开发中写一个跑 ...

  4. react实战项目开发(2) react几个重要概念以及JSX语法

    前言 前面我们已经学习了利用官方脚手架搭建一套可以应用在生产环境下的React开发环境.那么今天这篇文章主要先了解几个react重要的概念,以及讲解本文的重要知识JSX语法 React重要概念 [思想 ...

  5. angular+ionic+cordova(实战项目开发中,持续更新自己学到的和遇到的)

    最近公司开始准备做app了,大佬选择了angular+ionic+corvoda的开发结构,但是对于刚刚才开始对angular才有一点点感觉的我,就像是被一击闷棍敲了,半天没反应过来,emmm,怎么办 ...

  6. react实战项目开发(1) 搭建react开发环境初始化项目(Create-react-app)

    前言 Create React App npm install -g create-react-app create-react-app my-app cd my-app npm start 执行命令 ...

  7. Android快乐贪吃蛇游戏实战项目开发教程-06虚拟方向键(五)绘制方向键箭头

    本系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html本系列教程项目源码GitHub地址:https://github.com/jack ...

  8. Android快乐贪吃蛇游戏实战项目开发教程-03虚拟方向键(二)绘制一个三角形

    该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html 一.绘制三角形 在上一篇文章中,我们已经新建了虚拟方向键的自定义控件Direct ...

  9. Android快乐贪吃蛇游戏实战项目开发教程-02虚拟方向键(一)自定义控件概述

    该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html 一.自定义控件简介 在本项目中,无论是游戏主区域还是虚拟方向键都是通过自定义控件 ...

随机推荐

  1. wordpress jwt-auth 多语言 jwt_auth_bad_iss的解决方法

    因为目前处理的 wordpress 网站使用了,使用 qtranslate-x 多语言插件 JWT Authentication for WP REST API 插件 rest api 登录 调用wp ...

  2. [symonfy] An error occurred when executing the "'cache:clear --no-warmup'"

    Symfony Version: 3.4.* 当运行 composer update 会出现 [RuntimeException] An error occurred when executing t ...

  3. ie中报错---不能执行已释放 Script 的代码

    我的原因:使用jquery.colorbox.js.在页面中使用弹框,对于父页面中的变量进行修改(弹框页面的js--window.parent.obj.arr= 数组;), 当弹框关闭之后,在父页面中 ...

  4. loj2509 hnoi2018排列

    题意:对于a数组,求它的一个合法排列的最大权值.合法排列:对于任意j,k,如果a[p[j]]=p[k],那么k<j. 权值:sigma(a[p[i]]*i).n<=50W. 标程: #in ...

  5. VUE下echarts宽度响应式

    window.addEventListener("resize", () => { myChart2.resize();});

  6. {Django基础七之Ajax} 一 Ajax简介 二 Ajax使用 三 Ajax请求设置csrf_token 四 关于json 五 补充一个SweetAlert插件(了解)

    {Django基础七之Ajax} 一 Ajax简介 二 Ajax使用 三 Ajax请求设置csrf_token 四 关于json 五 补充一个SweetAlert插件(了解)   Django基础七之 ...

  7. 让footer固定在页面底部(CSS-Sticky-Footer)

    让footer固定在页面底部(CSS-Sticky-Footer)     这是一个让网站footer固定在浏览器(页面内容小于浏览器高度时)/页面底部的技巧.由HTML和CSS实现,没有令人讨厌的h ...

  8. ireport 无法打开问题

    打开时闪退 ,是因为jdk版本过高的原因:https://blog.csdn.net/aust_glj/article/details/52291240 相关软件下载地址: JasperReports ...

  9. Spring Boot配置公共的线程池

    内存资源很宝贵,线程池资源不宜过多的创建,同一个应用,尽量使用统一的线程池,并且相关参数需要设置适当,不造成资源的浪费,也不影响性能的提升. import java.util.concurrent.T ...

  10. C语言开发系列-二进制

    n位二进制的取值范围 -2的n-1次方 ~ 2的n-1次方-1 输出一个整数的二进制的存储形式 #include <stdio.h> // 输出一个整数的二进制的存储形式 void put ...