将js进行到底:node学习4
使用Node做web开发
HTTP与TCP
上一回使用node.js的NET(TCP)模块开发了一个聊天室demo。单纯用到了原始的TCP协议,可以说TCP是HTTP,SMTP,FTP的鼻祖了,后面的应用层协议都是基于TCP/IP协议的扩展。
接下来讨论的HTTP就是TCP上层的。
在node中TCP与HTTP的区别
创建TCP服务:
//tcp服务
require("net").createServer(function(conn){
//在创建服务后回调函数获得一个连接引用
//每一次TCP访问,甚至于http(可降级为tcp),都会产生一个基本的conn!
//我们将要在连接上做的事情,从客户端获取数据,返回数据给客户端都基于这个conn,上一章也展示了多个conn的使用
}).listen(3000);
创建HTTP服务:
require("http").createServer(function(req,res){
//在创建服务后回调函数获得两个参数,分别是请求request与响应response,这很类似于Java Servlet中的HttpRequest和HttpResponse对象,其实不同语言,不同平台虽然语法,习惯,框架不同,但是基础思想都得遵循http协议规范,这就是规范的作用:使得开发统一,简单!
//req对象中有获得客户端数据的各种方法
//res对象可以向客户端发送响应数据
//每一个客户端每一次请求都会创建一对req与res!
})。listen(3000);
HTTP可降级,但TCP不可升级:
我们知道浏览器一般必须访问http服务器(严格来说ftp也可以),至少说TCP服务是浏览器访问不了的,我们可以测试一个事情:HTTP服务可以被TCP客户端捕获,但是TCP服务无法被HTTP的客户端请求到:
代码1:TCP服务器
//这是一个tcp服务
var tcp = require("net");
tcp.createServer(function(conn){
conn.write("hello world");
}).listen(3000);
浏览器(http客户端)访问不到:
telnet(tcp客户端)可以访问到:
代码2:HTTP服务器
//这是一个http服务
var http = require("http");
http.createServer(function(req,res){
res.end("hello world");
}).listen(3000);
浏览器(http客户端)可以访问:
Telnet(TCP客户端)可以降级访问:
注意:如果是windows系统的telnet,有可能在telnet localhost 3000后一片漆黑啥都没有,什么都不管直接输入:“GET / HTTP/1.1”注意GET后面空格斜杠空格不能少!然后HTTP后面是没有空格的,总之最后就能看到啦!
这里,我们的发现就很有意思了,TCP的可以看到HTTP的,但HTTP却不能看到TCP的数据,这就充分说明TCP相当于是HTTP的父类,是更加基础,更加简单的协议,http更加复杂,降级后可以被TCP看到!
HTTP的头信息
对于HTTP这协议来说,传输的可以是文本,二进制文件,html富文本,xml,json等等,我们是需要告诉浏览器我们服务器传给你的是啥文件,这样浏览器才能知道如何解析收到的数据,而这个文件类型就在content-type中声明,我们做两个测试对比一下,看看浏览器如何识别:
直接返回html:
var http = require("http");
http.createServer(function(req,res){
res.writeHead(200);
res.end("sss<h1>hello world</h1>");
}).listen(3000)
无法解析html的h1标记,变成了纯文本输出(这里如果去掉前面sss单独输出一个h1标记是会被chrome浏览器默认当html解析的)
加入content-type声明后:
var http = require("http");
http.createServer(function(req,res){
res.writeHead(200,{"content-type":"text/html"});
res.end("sss<h1>hello world</h1>");
}).listen(3000);
这里的hello world就被识别为h1标记内容了!
当然,content-type有很多,这里不一一解释,详细参考:http://tool.oschina.net/commons/
返回文件
如果每一次都是使用res.end()返回字符串,形成一个完整的网页是不方便的
所以可以通过与Node FS模块联合,通过读取html文件来独立出html代码,在项目同级目录新建一个form.html
form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="">
<h1>表单测试</h1>
<label for="">姓名:</label>
<input type="text" placeholder="输入您的姓名">
</form>
</body>
</html>
index.js
var http = require("http");
var fs = require("fs");
http.createServer(function(req,res){
res.writeHead(200,{"content-type":"text/html"});
fs.createReadStream("form.html").pipe(res);
}).listen(3000);
注意:代码中引入了fs模块,即文件系统模块,通过学过的读取流,读取一个html文件,然后pipe是“管道”的意思,作用是将I/O管道里文件流对接到res响应流(其实也是I/O管道),好比自来水管相接,水就从一家到另一家了的道理。
这之间所有的流操作都是异步执行的,无论哪一根管道“水”慢了都不会阻塞node.js的运作,node任然能处理其他的请求!这就充分表现了node强大的异步性。
效果
这样就将html代码分离出来了,降低了代码耦合性。
像这样的非阻塞文件流操作在大文件传输方面,例如一些图片的加载,则性能尤为突出,如下使用node.js发送给客户端一张图片!
访问图片:
我们先往项目目录中放一张“psd.jpg”
var http = require("http");
var fs = require("fs");
http.createServer(function(req,res){
res.writeHead(200,{"content-type":"application/x-jpg"});
fs.createReadStream("psb.jpg").pipe(res);
}).listen(3000);
使用这招老套路的话,chrome浏览器会弹出让下载图片,而不是显示图片!下载后就是那一张图片了。这是因为我们没有给出img标签来要求浏览器显示这张图片
万全之策:
为了让图文正常显示,使用如下代码:
var http = require("http");
var fs = require("fs");
http.createServer(function(req,res){
//请求为图片
if(req.method == 'GET' && req.url.substr(-4)==".jpg"){
fs.stat(__dirname+req.url,function(err,stat){
if(err || !stat.isFile()){
res.writeHead(404);
res.end("找不到图片");
return;
}
serve(__dirname+req.url,'application/x-jpg');
});
}else if(req.method=="GET" && req.url=='/'){
serve(__dirname+'/form.html','text/html');
}else{
res.writeHead(404);
res.end("网址丢了");
return;
}
//独立response函数
function serve(path,content_type){
res.writeHead(200,{"content-type":content_type});
fs.createReadStream(path).pipe(res);
}
}).listen(3000);
效果:
这时候网页和图片都能正常显示了!
这章已经到了HTTP,就到了Node.js的核心了,因为node最广泛的应用是在http服务上,所以这一章说不掉多少node中http的知识和问题,只能下一章继续聊http了。
将js进行到底:node学习4的更多相关文章
- 【特别推荐】Node.js 入门教程和学习资源汇总
这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...
- Node.js 入门教程和学习资源汇总
这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...
- Node.js环境搭建和学习(windwos环境)
Node.js环境搭建和学习 一.环境搭建 1.下载安装文件 下载地址http://nodejs-org.qiniudn.com/下载Node.js环境安装包,根据操作系统下载对应的安装包 下载地址 ...
- node 学习笔记 - Modules 模块加载系统 (1)
本文同步自我的个人博客:http://www.52cik.com/2015/12/11/learn-node-modules-path.html 用了这么久的 require,但却没有系统的学习过 n ...
- [学姿势]实验室搬砖+node学习
这周开始进行收尾工作,我当然没有进行核心技术的开发,主要负责的是对web端进行展示上的修修补补,主要包括添加VLC播放器.rtsp视频流以及一些js细节. 1.VLC 全称为Video Lan Cli ...
- 2015第40周二Node学习
node历史 今天看cnode开源项目用了io.js,在查这个项目时发现这篇文章node历史,node.js和io.js关系谈到Node.js的由来,不可避免要聊到它的创始人Ryan Dahl.在20 ...
- 2015第40周一Node学习
node学习尝试 早上看了张丹大牛博客文章nodeJS学习路线图和node从零入门系列,感觉获益匪浅,尝试了里面几项内容,对node有了更深入的认识. npm npm是一个node包管理和分发工具,已 ...
- Node学习——开篇
前言:自从下决心转学前端以来,我的专业课java基本荒废了,所以对于后台开发的逻辑也已基本忘干净了.但是作为一名准前端程序猿,我认为还是有必要了解后端开发的,虽不必深入学习,但是能够了解项目从前端到后 ...
- node 学习资料
Node 学习资料: 资料名称 网址 Node.js 中文API文档 http://nodejs.cn/api/ Node 菜鸟教程 http://www.runoob.com/nodejs/node ...
- Node学习HTTP模块(HTTP 服务器与客户端)
Node学习HTTP模块(HTTP 服务器与客户端) Node.js 标准库提供了 http 模块,其中封装了一个高效的 HTTP 服务器和一个简易的HTTP 客户端.http.Server 是一个基 ...
随机推荐
- springboot cloud 网盘
boot https://pan.baidu.com/s/12SkGJNu_M-I-pjg-GxqHRw 5uga boot-cloud https://pan.baidu.com/s/1gO ...
- 文献管理器endnote学习笔记
目录 文献管理器endnote学习笔记 一.文献信息输入(将文献信息添加到文献管理软件endnote的多种方法) 1.在线检索(方便快捷,但有些网站无法直接检索) 2.网站输出(所有网站都支持的方式, ...
- C#通过窗体应用程序操作数据库(增删改查)
为了体现面向对象的思想,我们把“增删改查”这些函数封装到一个数据库操作类里: 为了便于窗体程序与数据库之间进行数据交互,我们建一个具有数据库行数据的类,通过它方便的在窗体程序与数据库之间传输数据: 我 ...
- C/C++ memcpy函数的用法
功能 memcpy指的是c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中 头文件 所在头文件 <s ...
- 高精度处理斐波那契序列(C语言)
#include<stdio.h> #include<string.h> //memset,strcpy,strlen函数头文件 int main(void) { ];//用来 ...
- Windows系统清理
@echo off del/f/s/q %systemdrive%\*.tmp del/f/s/q %systemdrive%\*._mp del/f/s/q %systemdrive%\*.log ...
- EXAM-2018-08-21
EXAM-2018-08-21 自己真的是菜的恐怖 D:Fence Building 欧拉公式:V-E+F=2 在平面中:V为顶点个数,E为边数,F为区域数 在简单几何体中:V为顶点个数,E为边数,F ...
- 量化投资_MATLAB在时间序列建模预测及程序代码
1 ARMA时间序列机器特性 下面介绍一种重要的平稳时间序列——ARMA时间序列. ARMA时间序列分为三种: AR模型,auto regressiv model MA模型,moving averag ...
- shell_innobackup增量备份步骤
alias start='service mysql.server start'alias restart='service mysql.server restart'alias stop='serv ...
- 记一次线上“no such file or directory”问题处理
事件背景描述:项目是基于docker部署,在使用xxl-job的过程中,需要使用XxlJobLogger.log记录日志(非必须),项目定义日志其日志存储位置/home/logs.任务运行后包找不到文 ...