前端与nodeJS的那些事

1.模块系统

对比:

原网页 新网页
前端 require.js define定义模块
node.js reueire.js exports定义模块

Demo:

//原网页中模块化开发的写法;
    require("./3.2search.js").search(req,res,connection);

//新网页中模块化开发的写法
    function search(req,res,connection){
        var value = req.body.value;  //获取Post请求发送过来的参数;
         //console.log('SELECT * FROM user where username="'+value+'"') //用这种打印方法判断输入的SQL命令是否正确;
        //连接数据库并返回数据;
        connection.query('SELECT * FROM user where username="'+value+'"', function(error, results, fields) {
            if(error) throw error;
            //results =>array类型
            res.send(JSON.stringify(results));
        });
        //connection.end();
}
exports.search =search;

//详见3.2express中post请求;

2.node.js

创建服务器

http.createServer

//引入http内置模块
var http = require("http");
http.createServer(function(request,response){
    //设置响应头;
    response.setHeader("Access-Control-Allow-Origin","*");
    //返回结果 
    //注意:结果值必须是字符串;否则转成JSON.stringify(data) 或者 拼接('"'+data+'"')
    response.end("Hello World");  //=>JSON.stringify(data)
}).listen(12345)
//端口号有范围限制0~65535

注意点:

1.http.createServer (代替了php+apache)

2.创建的服务器是指向xxx.js执行后的域名和端口号;请求的地址要填写服务器地址;

Demo

----提取前端发来的参数;
get请求:接收传递过来的参数

/*前端传递
    data:{type:post,name:heightzhang},
    dataType:'json'*/
//创建服务器
var http = require("http");
//引入url模块
var url =require('url');
//=>引入querystring模块处理参数(作用:将url参数转为对象);
var querystring = require('querystring') //将传递过来的type=post&name=heightzhang 参数转成对象;
http.createServer(function(request,response){
    //设置响应头;
    response.setHeader("Access-Control-Allow-Origin","*");

    //处理传递过来的参数并且打印出来
    var paramStr  = url.parse(request.url).query; //console.log(request.url)=>/?type=post&name=heightzhang
    //console.log(url.parse(request.url))//url.parse方法后,有query哈希值属性,也有path路由属性;
    
    //consle.log(paramStr)=>type=post&&name=heightzhang;
    var param = querystring.parse(paramStr);//console.log(param)=>{type:post,name:heightzhang}

    response.end(JSON.stringify(param))

}).listen(12345)

post请求:接收传递过来的参数;

//创建服务器
var http = require("http");
/*前端传递
    data:{type:post,name:heightzhang},
    dataType:'json'*/
//=>引入querystring模块处理参数(将url参数转为对象);
var querystring = require('querystring') //将传递过来的type=post&name=heightzhang 参数转成对象;
http.createServer(function(request,response){
    //设置响应头;
    response.setHeader("Access-Control-Allow-Origin","*");

    //接收传递过来的参数;
    var post ="";
    request.on("data",function(msg){//data是固定的;
                      //msg为Buffer值;
        post += msg;  //console.log(post);=>type=post&name=heightzhang 
        post = querystring.parse(post);//console.log(post)=>{type:post,name:heightzhang}
        
    });
    
    request.on('end',function(){
         //请求结束后响应头返回前端,返回前端值为:{type:post,name:heightzhang} 
        response.end(JSON.stringify(post))
    });
}).listen(12345)

<b><span style="color: red">注意</span>
传递给前端

只支持字符串,如果是变量,要先用JSON.stringify转换</b>

表格对比 PHP与node.js

角度 php nodejs
- - -
解析引擎 Apache解析 Node(V8)解析
服务器创建 Apache创建 http.createServer创建
- - -
AJAX.cros
服务端设置响应头
header("Access-Control-Allow-Origin:*"); response.setHeader("Access-Control-Allow-Origin","*")
输出给前端的结果值 echo xxx response.end("xxx")
- - -
提取GET请求的参数 $_GET["xxx"] 引入两个模块:url&&querystring
var paramStr = url.parse(request.url).query;
var param = querystring.parse(paramStr);
提取POST请求的参数 $_POST["xxx"] 引入一个模块:querystring+request.on语法

3.Mysql数据库

//引入数据库模块
var mysql = require("mysql");
//配置数据库的连接
var connection = mysql.createConnection({
    host:"localhost",
    user:"root",
    password:"",
    database:"login" //数据库地址;
});
//进行数据库连接
connection.connect();
//执行sql语句 
connection.query('SELECT username FROM user',function(error,results,fields){
    if(error) throw error;
    console.log('The solution is: ',results);
});
//关闭数据库链接
connection.end();

<b><span style="color: red">注意</span>
执行命令中

拼接:如果是变量,要加双引号,数字不用;</b>

4.Express

1)创建服务器

    //使用express模块
var express = require('express');
var app =express();

//不能直接输出结果,输出结果要借助app.GET/POST/ALL方法输出;

var server =app.listen(8081,function(){
    var host = server.address().address;
    var port = server.address().port;
    //console.log(port) port 为端口名称;
}); //该代码块 等同于 app.listen(8081);

2)GET请求处理参数

//引入express模块
var express = require('express');
var app =express();
// ------------get请求-------------------
app.get('/',function(req,res){
    获取get请求发送过来的参数; 
    //设置响应头;
    res.append("Access-Control-Allow-Origin","*");

    //请求头返回给前端
    var abc =req.query  //console.log(req.query)=>{name:heightzhang}
    res.send(abc) //可以直接返回变量(数组或对象),不需要像原生一样JSON.stringify;
    
});
var server =app.listen(8081,function(){
    var host = server.address().address;
    var port = server.address().port;
    //console.log(port) port 为端口名称;
});

3)POST请求处理参数

/*前端data:{name:"heightzhang"}*/
//引入express模块
var express = require('express');
var app =express();
//引入bodyParser模块,处理post参数
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended:false}));

// ---------post请求---------------------
app.post('/',function(req,res){
    //设置响应头;
    res.append("Access-Control-Allow-Origin","*");

    //响应头返回给前端;
    var post = req.body;//console.log(req.query)=>{name:heightzhang}
    res.send(post)
});
var server =app.listen(8081,function(){
    var host = server.address().address;
    var port = server.address().port;
    //console.log(port) port 为端口名称;
});

4)混合写法All请求处理参数

//引入express模块
var express = require('express');
var app =express();
//引入bodyParser模块,处理post参数
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended:false}));

// ---------all请求---------------------
app.all('/',function(req,res){
    //设置响应头;
    res.append("Access-Control-Allow-Origin","*");

    //console.log(req.query) =>请求头数据 get参数 
    //console.log(req.body)=>响应头数据 post参数

    //响应头返回给前端; //获取post请求参数
    res.send(post)

});
var server =app.listen(8081,function(){
    var host = server.address().address;
    var port = server.address().port;
    //console.log(port) port 为端口名称;
});

5)总结

- 模块
get
post bodyParser

表格对比 nodejs 与express

nodejs express
创建服务器 http.createServer app.listen
AJAX.cros服务端设置响应头 response.setHeader("Access-Control-Allow-Origin","*") res.append("Access-Control-Allow-Origin","*");
提取GET请求的参数 url.parse.query&&querystring req.query
提取POST请求的参数 querystring&&request.on语法 bodyParser&&req.body
输出给前端的结果值 response.end(不支持变量) res.send(支持变量)

5.Node.js服务器代理(http.request)

第一种:http.request({});

//node代理PHP服务器;
 var http = require("http");

//理解:相当于nodejs向php发送了"ajax请求",用http.request方法;
//http://localhost/three/test.php =>PHP的服务器地址;
http.request({
    hostname: 'localhost',
    port: '80',
    path: '/three/test.php?name=heightzhang',
    method: 'GET'
}, function(res) {
    res.setEncoding('utf8');
    var data = "";
    res.on('data', function(chunk){
        data += chunk
    });
    res.on('end', function(){
        //接收连接服务器后返回的数据
        console.log(data);
    });
}).on('error', function(e) {
    console.log('problem with request: ' + e.message);
}).end();

第二种:http.get 用的比较多;

var https = require("https");
exports.fetch = function(url, callback) {
    https.get(url, function(res) {
        var data = "";
        res.on('data', function(chunk) {
            data += chunk
        })
        res.on('end', function() {
            callback(data)
        })
    })
}

项目:nodejs的优化层;

var express = require('express');
var http = require("http");
var fs = require("fs")

var app = express();

//boydy模块接收传递过来的post值;
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended:false}));


//中间层
app.all('/', function(req, res) {
    //设置请求头;
    res.append("Access-Control-Allow-Origin","*");  
    //接收post请求发送过来的参数;
    var username = req.body.username;
    var password =req.body.password;

    //一 nodejs专门写文件 记录日志;支持HTML标签;
    fs.readFile("log.txt", function(err, data) {
            //data.toString() 文件值;
            //console.log(req.query.name); req.query.name 为 laoxie;
            var content = data.toString() + '用户名:'+username + "   ";
            fs.writeFile("log.txt", content, function(err) {
            })
    });
//二 -------- 通信php 相当于node发送AJAX请求给PHP;---------------
    //php专门存数据库
    http.request({
    //http://localhost/exam/api/register.php
    hostname: 'localhost',
    port: '80',
    path: '/exam/api/register.php?username='+username+'&password='+password,
    method: 'GET'
    }, function(rea) {
        rea.setEncoding('utf8');
        var data = "";
        rea.on('data', function(chunk){//rea.on不是post请求的内容吗?也可以设为php传回来的参数吗
            data += chunk;  
        });
        rea.on('end', function(){   
            //php返回的值data  res.send=>将nodejs中的data返回给前端;
            //注意 :http.request请求中的rea同all中的res不是同一个值;
            //传递post请求参数给php; 服务器与服务器中一般用get请求;
            console.log(data);res.send(data);
        });
        
    }).on('error', function(e) {
        console.log('problem with request: ' + e.message);
    }).end();
//-----------------------------------------------------------------
    //res.send("1111");
    
})
app.listen(10086)

原理图:

[图片上传失败...(image-d857e0-1524822238442)]

6.爬虫=>数据库=>下载

/*爬虫的关键模块是cheerion模块
    爬虫的目的:写入数据库; 下载内容;
*/
var http =require("http");
//nodejs版本里面的JQ
var cheerio = require("cheerio");
//连接数据库
var mysql = require("mysql");
//文件系统
var fs = require("fs");

var connection = mysql.createConnection({
    host:"localhost",
    user:"root",
    password:"",
    database:"login"
});
connection.connect();

http.get("http://www.mzitu.com/zipai/comment-page-1/",function(res){
    var data = "";
    res.on("data",function(chunk){
        data += chunk
    });
    res.on("end",function(){
        //console.log(data);拿到数据;
        //将数据写入cheerio后进行爬虫处理

        var $ = cheerio.load(data);
        var imgArr = [];
        $('img').each(function(index,ele){
            //爬虫后获得的数据如下
            //console.log($(ele).attr("src"));
            //1.爬虫后写入数据库;
            // connection.query('INSERT INTO `text`(`name`, `url`) VALUES ("' + index + '","' + $(ele).attr("src") + '")', function(error, results, fields) {
            //  if(error) throw error;
            //  console.log('The solution is: ', results);
            // });
            imgArr.push($(ele).attr("src"));
        });
        //2.爬虫后下载内容
        download(imgArr);
    })

});
var i = 0; //问题:i 的放置问题,为什么down()执行在var i =0 的上方依然可以读取到值?
            //不是应该打印出来变量声明提前,underfine的吗;
//封装下载函数(下载多张)
function download(imgArr){
    var length = imgArr.length;
    //重新命名;
    var writerStream = fs.createWriteStream("../img/"+i+".jpg");
    //读取远程地址的图片,并复制到本地;
    http.get(imgArr[i],function(res){
        //res为读取流 , 通过管道 将 读取流 写入 写入流;
        res.pipe(writerStream);
        //递归 写完第一个图片后再下载第二张;
        if(i<length){
            i++;
            console.log("完成第"+i+"/"+length+"张");
            download(imgArr);
        }else{
            return;
        }
    })
};

7.文件系统

读写流

//引入文件系统模块;
var fs = require("fs");
//读取流,读取任意文件;
var readerStream = fs.createReadStream('../img/11.jpg');
// 写入流,创建新文件,自动生成;
var writerStream = fs. createWriteStream('5.2writerStream.txt');

//读取的文件复制给写入的文件里面(可以是流(视频,图片),字符串);
readerStream.pipe(writerStream);console.log(readerStream)

缓冲流

1)读取文件

var fs = require("fs");//文件系统

fs.readFile("5.4test.txt",function(err,data){
    //console.log(data) =>缓冲流Buffer 64 64 61 66 66 61

    //toString() => 把缓冲流(数据)转化为字符串
    console.log(data.toString())
})//异步

2)写入文件

var fs = require("fs");//文件系统
    var content = `12345`   //预定义该文件的内容;支持HTML标签;
    //自动创建新文件并且写入,
    fs.writeFile("5.5test.txt",content,function(err){将content写入该文件

    })

<span style="color: red">读写流是分一部分一部分地写,缓冲流是一次性写入,所以在处理大型文件的时候一般用读写流的形式读或者写</span>

上传图片

引入multer模块;

//引入express框架
var express = require("express");
var app = express();
app.listen(3200);

var multer = require('multer');

var storage = multer.diskStorage({
    //设置上传后文件路径,uploads文件夹需要手动创建。
    destination: function(req, file, cb) {
        cb(null, './uploads')
    },
    //给上传文件重命名
    filename: function(req, file, cb) {
        var fileFormat = (file.originalname).split(".");
        //图片命名规则:name名+时间戳(防止重命名)+后缀名;
        //注意:file.fieldname为input files html标签的name名;
        //比如把 abc.jpg图片切割为数组[abc,jpg],然后用数组长度-1来获取后缀名
        cb(null, file.fieldname+ '-' + Date.now() + "." + fileFormat[fileFormat.length - 1]);
    }
});
var upload = multer({
    storage: storage
});

//单图上传
//app.post('/upload-single', upload.single('logo'), function(req, res, next) {
//多图上传
app.post('/upload-single', upload.any(), function(req, res, next) { 
    res.append("Access-Control-Allow-Origin","*");
    res.send({
        wscats_code: '0'
    });
});

html部分

$.ajax({
                url: 'http://localhost:3200/upload-single',
                type: 'POST',
                cache: false, //不必须
                data: new FormData($('#uploadForm')[0]),
                processData: false,
                contentType: false,
                success: function(data) {
                    console.log(data)
                }
            })
        }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • https://nodejs.org/api/documentation.html 工具模块 Assert 测试 ...
    KeKeMars阅读 6,221评论 0 6
  • Node.js是目前非常火热的技术,但是它的诞生经历却很奇特。 众所周知,在Netscape设计出JavaScri...
    w_zhuan阅读 3,578评论 2 41
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,507评论 6 13
  • 资产负债表:资产即为公司所拥有的钱和物,包括投资理财的钱等。而负债是指公司欠人家的钱。 所有者权益=资产-负债,这...
    w小郭阅读 110评论 0 0