zoukankan      html  css  js  c++  java
  • 将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了。

  • 相关阅读:
    设计模式のPrototypePattern(原型模式)----创建模式
    设计模式のBuilderPattern(创建者模式)----创建模式
    设计模式のSingleton Pattern(单例模式)----创建模式
    设计模式のAbstractFactory(虚拟工厂)----创建模式
    设计模式のFactoryPattern(工厂模式)----创建模式
    日文键盘改英文键盘
    [转]CString转char * ,string
    linux下添加PATH环境变量
    Windows异步套接字(WSASocket)
    【转载】va_start和va_end使用详解
  • 原文地址:https://www.cnblogs.com/devilyouwei/p/8432682.html
Copyright © 2011-2022 走看看