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)
注意
传递给前端
只支持字符串,如果是变量,要先用JSON.stringify转换
表格对比 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();
注意
执行命令中
拼接:如果是变量,要加双引号,数字不用;
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
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写入该文件
})
读写流是分一部分一部分地写,缓冲流是一次性写入,所以在处理大型文件的时候一般用读写流的形式读或者写
- [详情参考w3c-school的官方文档]-https://www.w3cschool.cn/nodejs/nodejs-stream.html
上传图片
引入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)
}
})
}