当前位置: 澳门新濠3559 > 编程 > 正文

服务器可以监听客户端的请求,也敬请期待我们

时间:2019-12-27 17:08来源:编程
大神帮忙看看,照着书上敲的。constrequest=require('request');constpath=require('path');constconfig=require('./config');constanalyze=require('./analyze');functiondownLoad(imgUrl,i){letext=imgUrl.split('.').pop();request(imgUrl).

大神帮忙看看,照着书上敲的。constrequest=require('request');constpath=require('path');constconfig=require('./config');constanalyze=require('./analyze');functiondownLoad(imgUrl,i){letext=imgUrl.split('.').pop();request(imgUrl).pipe(fs.createWriteStream(path.join(config,imgDir,i+'.'+ext),{'encoding':'utf-8'}))console.log(i);}functionstart(){request(config.url,function(err,res,body){console.log('start');if(!errres){console.log('start');analyze.findImg(body,downLoad);}})}start();这是我的代码启动之后显示这个,说我fs有错误,百度了很多找不到办法E:Nodeindex.js:9request(imgUrl).pipe(fs.createWriteStream(path.join(config,imgDir,i+'.'+ext),{^ReferenceError:fsisnotdefinedatdownLoad(E:Nodeindex.js:9:23)atNode.anonymous(E:Nodeanalyze.js:6:3)atinitialize.exports.each(E:Nodenode_modulescheeriolibapitraversing.js:300:24)atObject.findImg(E:Nodeanalyze.js:4:11)atRequest._callback(E:Nodeindex.js:21:12)atRequest.self.callback(E:Nodenode_modulesrequestrequest.js:185:22)atRequest.emit(events.js:198:13)atRequest.anonymous(E:Nodenode_modulesrequestrequest.js:1161:10)atRequest.emit(events.js:198:13)atIncomingMessage.anonymous(E:Nodenode_modulesrequestrequest.js:1083:12)

Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高。
nodejs由以下模块组成:
引入 required 模块:我们可以使用 require 指令来载入 Node.js 模块。
创建服务器:服务器可以监听客户端的请求,类似于 Apache 、Nginx 等 HTTP 服务器。
接收请求与响应请求 服务器很容易创建,客户端可以使用浏览器或终端发送 HTTP 请求,服务器接收请求后返回响应数据。

const Promise = require('bluebird')

图片 1

创建服务器
首先要引入http模块
var http = require("http");
通过
http.createServer() 方法创建服务器
demo:
var http = require('http');http.createServer(function (request, response) { // 发送 HTTP 头部 // HTTP 状态值: 200 : OK // 内容类型: text/plain response.writeHead(200, {'Content-Type': 'text/plain'}); // 发送响应数据 "Hello World" response.end('Hello Worldn');}).listen(8888);// 终端打印如下信息console.log('Server running at ');
写入数据可以使用write()
response.write("Hello World");
response.write(" IAM LQ");
response.write(data.toString());
response.end();

const requestPro = Promise.promisify(request)

图片 2

使用package.json
npm init 去创建

const cheerio = require('cheerio')

本教程总共7篇,每日更新一篇,请关注我们!你可以进入历史消息查看以往文章,也敬请期待我们的新文章!

Node.js REPL交互式解释器
http://www.runoob.com/nodejs/nodejs-repl.html

let pageUrl =''

1.React多页面应用1(webpack开发环境搭建,包括Babel、热更新等) ----2017.12.28

Nodejs 回调函数
demo:
var http=require('http');//http服务
var fs = require("fs");//读取文件
http.createServer(function(request,response){
response.writeHead(200,{'Content-Type':'text/plain'});
//读取文件信息 将返回值 给response
//var data = fs.readFileSync('input.txt'); 这种方式 是 同步
fs.readFile('message.txt', function (err, data) {
if (err) return console.error(err);
response.end(data.toString());
});
}).listen(8888);

async function crawPics(url, dirname) {

2.React多页面应用2(处理CSS及图片,引入postCSS及图片处理等)----2017.12.29

console.log('运行在 http://localhost:"8888');

    let html = await requestPro({ url }).then(response => response.body)

3.React多页面应用3(webpack性能提升,包括打包性能、提取公共包等)----2017.12.30

Nodejs 事件循环
绑定和监听事件 需要引入events 模块 并且通过EventEmitter 类来绑定和监听事件
eventEmitter.on('你起的名字',function(){
//这里是这个事件对应的do something
})
eventEmitter.emit('你起的名字');//这样子去执行你写好的事件

    $ = cheerio.load(html)

4.React多页面应用4(webpack自动化生成多入口页面)----2017.12.31

demo:
// 引入 events 模块
服务器可以监听客户端的请求,也敬请期待我们的新文章。var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();

    // let imgUrls = $('a.collection img').attr('src')//也不知为啥这句话不能用

5.React多页面应用5(webpack生产环境配置,包括压缩js代码,图片转码等)----2018.01.01

//创建链接函数
eventEmitter.on('connection',function(){
console.log('链接成功');
eventEmitter.emit('data_received');
});

    let imgUrls=Array.from($('a.collection').find('img')).map((element) =>element.attribs.src.split("?").shift())

6.React多页面应用6(gulp自动化发布到多个环境,生成版本号,打包成zip等)----2018.01.02

// 使用匿名函数绑定 data_received 事件
eventEmitter.on('data_received', function(){
console.log('数据接收成功。');
});

  console.log(imgUrls)

7.React多页面应用7(引入eslint代码检查)----2018.01.03

// 触发 connection 事件
eventEmitter.emit('connection');

    imgUrls.forEach(async (imgUrl,index) => {

开发环境:Windows 8,node v8.9.1,npm 5.5.1,WebStorm 2017.2.2

console.log("程序执行完毕。");

        console.log(imgUrl)

在之前课程中,我们发现,有很多重复劳动

Buffer缓冲区
专门存放二进制数据
new Buffer创建buffer对象实例 write返回实际写入的大小
写入demo:
var buf = new Buffer(256);
var len = buf.write("www.runoob.cn",0,8,"utf8");//数据,开始下标,能存多少位,编码方式

        console.log(`${dirname}\cup${index}.jpg`)

如:

console.log("写入字节数 : "+ len);//8
存入汉子并且打印出来:
var buf = new Buffer('你好我是数据');

        request('http:'+imgUrl).pipe(fs.createWriteStream( `${dirname}\cup${index}.jpg`))

我们需要手动新建webpack入口文件

console.log(buf.toString());
合并buffer:
var buffer1 = new Buffer('菜鸟教程 ');var buffer2 = new Buffer('www.runoob.com');var;var) buffer3 = Buffer.concat([buffer1,buffer2]);console.log("buffer3 内容: " + buffer3.toString());

    });

再 entryBuild 文件夹中新建,每个页面的js文件

Node.js Stream(流)
http 服务器发起请求的request 对象就是一个 Stream

}

index.js

createWriteStream//写入流
createReadStream//读取流
创建对象并且指向文件对象
var readerStream = fs.createReadStream('input.txt');
var writerStream = fs.createWriteStream('output.txt');
写入数据 并且定义编码规范
var data='我是写入的数据'
writerStream.write(data,'UTF8');
读取数据并且打印
// 设置编码为 utf8。
var data='';
readerStream.setEncoding('utf8');
// 读取数据并且打印
readerStream.on('data', function(data) {
data = data;
console.log(data);
});
以下是数据copy 一个文件读取存入另一个文件
var fs = require("fs");

crawPics(pageUrl,path.join(__dirname, 'cup'))

shop.js

// 创建一个可读流
var readerStream = fs.createReadStream('message.txt');

但是头疼的是不知$('a.collection img').attr('src')为啥不能用了,到底attr与attribs怎么区分啊,还是cheerio已经更新了。不过这个demo我测试了 ,能用。也比较简洁了。

这两个文件 几乎是一样的

// 创建一个可写流
var writerStream = fs.createWriteStream('book.txt');

da

然后还需要在 build 文件夹中建立

// 管道读写操作
// 读取 input.txt 文件内容,并将内容写入到 output.txt 文件中
readerStream.pipe(writerStream);

两个对应的 html文件

console.log("程序执行完毕");
压缩文件
var fs = require("fs");var zlib = require('zlib');// 压缩 input.txt 文件为 input.txt.gzfs.createReadStream('input.txt') .pipe(zlib.createGzip()) .pipe(fs.createWriteStream('input.txt.gz')); console.log("文件压缩完成。");
解压文件
var fs = require("fs");var zlib = require('zlib');// 解压 input.txt.gz 文件为 input.txtfs.createReadStream('input.txt.gz') .pipe(zlib.createGunzip()) .pipe(fs.createWriteStream('input.txt')); console.log("文件解压完成。");

index.html

nodejs 模块系统
优先加载原生模块 例如http、fs、path等
var http=require('http');
module.exports=function(){} or 对象

shop.html

Nodejs函数
和JS一样

这两个文件几乎也是一样的

nodejs路由
我们需要的所有数据都会包含在request对象中,该对象作为onRequest()回调函数的第一个参数传递。但是为了解析这些数据,我们需要额外的Node.JS模块,它们分别是url和querystring模块。
说白了就是路径
var pathname = url.parse('http://baidu.com/a/b?a=1').pathname.pathname);
var router=url.parse('http://baidu.com/a/b?a=1').query.query)
response.write(pathname+" "+router);

顺便还有一个问题就是 

会出现 /a/b a=1

title 如何设置?

node全局对象
response.write(__filename);D:nodejsdemoglobal.js
response.write(__dirname);D:nodejsdemo
setTimeout(cb, ms)
clearTimeout(t)
setInterval(cb, ms)
console
process process 是一个全局变量,即 global 对象的属性。 和系统交互要用到

描述 和 关键词 如何设置?

nodejs常用工具 util
util 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心JavaScript 的功能 过于精简的不足。
用于继承
util.inherits(child,parent)
只能继承原型中定义的函数 即通过prototype扩展的函数
构造函数内部创造的不继承
util.inspect任意对象转换 为字符串的方法,通常用于调试和错误输出。它至少接受一个参数 object,即要转换的对象。
util.isArray(object)如果给定的参数 "object" 是一个数组返回true,否则返回false。
util.isRegExp(object)如果给定的参数 "object" 是一个正则表达式返回true,否则返回false。
util.isDate(object)如果给定的参数 "object" 是一个日期返回true,否则返回false。
util.isError(object)如果给定的参数 "object" 是一个错误对象返回true,否则返回false。

我们现在来解决这些问题!!!!!!!!!!

应用框架Express
安装:npm install express --save
以下几个重要的模块需要与express一起安装:
$ npm install body-parser --save$ npm install cookie-parser --save$ npm install multer --save
body-parser 处理JSON RAW Text URL编码的数据
cookie-parser解析cookie的工具 通过req.cookies 可以取到传来的cookie 转成对象
multer 处理enctype="multpart/form-data"的表单数据
demo: 这里配置路由
var express=require('express');
var app=express();
app.get('/',function(req,res){
res.send('HELLO WORD2');
})
app.get('/app',function(req,res){
res.send('进入了另一个路径');
})
var server=app.listen(8888,function(){
var host=server.address().address
var port=server.address().port
console.log("应用实例,访问地址为 http://", host, port)
})
静态资源
app.use(express.static('public'))
http://localhost:8888/img/2.png 就不用写public了

设置 entry 入口文件

设置路由 编写接口
var express=require('express');
var app=express();
//静态文件
app.use(express.static('public'))
//设置默认入口
app.get('/',function(req,res){
res.sendFile(__dirname+"/"+"index.html");
})
//接口
app.get('/message',function(req,res){
res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});//设置response编码为utf-8
obj={
id:req.query.id,
name:req.query.name
}
res.end(JSON.stringify(obj));
})
var server=app.listen(8888,function(){
var host=server.address().address
var port=server.address().port
console.log("应用实例,访问地址为 http://", host, port)
})

我们在 config 文件夹中 新建 entry.js ,以后我们新建页面,只需要在这里添加即可

Post的demo:必须要引入body-parser 需要安装依赖
var urlencodedParser = bodyParser.urlencoded({ extended: false }) 是必须的
var express=require('express');
var app=express();
var bodyParser = require('body-parser');
// 创建 application/x-www-form-urlencoded 编码解析
var urlencodedParser = bodyParser.urlencoded({ extended: false })
//静态文件
app.use(express.static('public'))
//设置默认入口
app.get('/',function(req,res){
res.sendFile(__dirname+"/"+"post.html");
})
//接口
app.post('/message',urlencodedParser,function(req,res){
res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});//设置response编码为utf-8
obj={
id:req.body.id,
name:req.body.name
}
res.end(JSON.stringify(obj));
})
var server=app.listen(8888,function(){
var host=server.address().address
var port=server.address().port
console.log("应用实例,访问地址为 http://", host, port)
})

path路径 会指向到 app->component 目录下

let entry = [

{

name:'index',

       path:'index/Index.jsx',

       title:'首页',

       keywords:'首页,xxx',

       description:'这是我们的首页'

   },

   {

name:'shop',

       path:'shop/Index.jsx',

       title:'商城',

       keywords:'商城,xxx',

       description:'这是我们的商城'

   }

];

module.exports = entry;

2.接下来 我们要实现 自动化 生成 , webpack 的入口文件js,和html文件

在这之前我们需要写几个公共方法!

在config下,新建common

建立copyFile.js

// js/app.js:指定确切的文件名。

// js/*.js:某个目录所有后缀名为js的文件。

// js/**/*.js:某个目录及其所有子目录中的所有后缀名为js的文件。

// !js/app.js:除了js/app.js以外的所有文件。

// *.+(js|css):匹配项目根目录下,所有后缀名为js或css的文件。

//流 stream   管道 pipe 管道

//如果想在读取流和写入流的时候做完全的控制,可以使用数据事件。但对于单纯的文件复制来说读取流和写入流可以通过管道来传输数据。

/*

* 复制目录中的所有文件包括子目录

* @src param{ String } 需要复制的目录   例 images 或者 .

* @dst param{ String } 复制到指定的目录    例 images images/

*/

const fs =require("fs");

const path =require("path");

//获取当前目录绝对路径,这里resolve()不传入参数

const filePath = path.resolve();

const copy =function(src,dst){

//判断文件需要时间,则必须同步

   if(fs.existsSync(src)){

fs.readdir(src,function(err,files){

if(err){console.log(err);return;}

files.forEach(function(filename){

//url+"/"+filename不能用/直接连接,Unix系统是”/“,Windows系统是”“

               var url = path.join(src,filename),

                   dest = path.join(dst,filename);

               console.log(url);

               console.log(dest);

               fs.stat(path.join(src,filename),function(err, stats){

if (err)throw err;

                   //是文件

                   if(stats.isFile()){

//创建读取流

                       readable = fs.createReadStream(url);

                       //创建写入流

                       writable = fs.createWriteStream(dest,{encoding:"utf8" });

                       // 通过管道来传输流

                       readable.pipe(writable);

                       //如果是目录

                   }else if(stats.isDirectory()){

exists( url, dest, copy );

                   }

});

           });

       });

   }else{

console.log("给定的目录不存,读取不到文件");

       return;

   }

};

function exists(url,dest,callback){

fs.exists(dest,function(exists){

if(exists){

callback && callback(url,dest);

       }else{

//第二个参数目录权限 ,默认0777(读写权限)

           fs.mkdir(dest,0777,function(err){

if (err)throw err;

               callback && callback(url,dest);

           });

       }

});

}

module.exports =copy;

建立deleteFile.js

const fs =require("fs");

const deleteFolderRecursive =function (path) {

if (fs.existsSync(path)) {

fs.readdirSync(path).forEach(function (file, index) {

let curPath = path +"/" + file;

           if (fs.lstatSync(curPath).isDirectory()) {// recurse

               deleteFolderRecursive(curPath);

           }else {// delete file

               fs.unlinkSync(curPath);

           }

});

       fs.rmdirSync(path);

   }

};

module.exports =deleteFolderRecursive;

建立 imgDel.js

let fs =require('fs');

let join =require('path').join;

/**

*

* @param startPath  起始目录文件夹路径

* @returns {Array}

*/

function findSync(startPath) {

let result = [];

   function finder(path) {

let files = fs.readdirSync(path);

       files.forEach((val, index) => {

let fPath = join(path, val);

           let stats = fs.statSync(fPath);

           if (stats.isDirectory())finder(fPath);

           if(val.indexOf('png') !==-1 ||val.indexOf('gif') !==-1 || val.indexOf('jpg') !==-1){

if (stats.isFile()) result.push(val.substring(0,val.length -12));

           }

});

   }

finder(startPath);

   return result;

}

let fileNames =findSync('pc/resource/');

console.log(fileNames);

建立 nodeCommon.js

const deleteFile =require("./deleteFile");

const copyFile =require("./copyFile");

module.exports = {

deleteFile,

   copyFile

};

建完后目录结构如下

3.新建entryBuild.js

const fs =require("fs");

const path =require("path");

const entry =require('./entry');

const nodeCommon =require('../common/nodeCommon');

const entryBuildPath = path.resolve(__dirname, '../../entryBuild');

nodeCommon.deleteFile(entryBuildPath);

fs.mkdirSync(entryBuildPath);

const entryContent = (data) => {

let cont =``;

   return `

import React from 'react';

import ReactDOM from 'react-dom';

import Index from '../app/component/${data.path}';

ReactDOM.render(${cont},document.getElementById('app'));

`

};

/*生成webpack entry 入口文件*/

entry.map((data) => {

fs.writeFile(entryBuildPath +'/' + data.name +'.js', entryContent(data), 'utf8', function (err) {

if (err) {

return console.log(err);

       }

});

});

4.修改 package.json 

"entry": "node config/entry/entryBuild.js",

我们现在 删除 entryBuild 文件夹

然后 执行 npm run entry

看下 是不是 创建了 entryBuild  文件夹 及 index.js shop.js

执行 npm run dev 

一切正常

5.接下来我们自动化生成 html文件

我们需要建立一个模版 比如叫 index.html

放在根目录下

   

   

   

   <%= htmlWebpackPlugin.options.title %>

6.建立几个公用webpack js文件

webpack.com.conf.js

let titleFun =function(chunkName,title){

let titleDef ='XXX网站';

   if(chunkName.indexOf('index') !==-1){

return titleDef;

   }else{

return title +'_' + titleDef;

   }

};

module.exports = {

titleFun:titleFun

};

添加依赖 

npmi -D copy-webpack-plugin clean-webpack-plugin

修改  webpack.file.conf.js 文件

const path =require("path");

const CopyWebpackPlugin =require('copy-webpack-plugin');

const CleanWebpackPlugin =require('clean-webpack-plugin');

function cleanFun(arr) {

return (new CleanWebpackPlugin(arr, {root: path.resolve(__dirname, '../../'), verbose:true, dry:false}))

}

let copyObj = [

/*{from: './app/public/plugin', to: './plugin'},

{from: './app/public/versionTips', to: './versionTips'},

{from: './app/public/file', to: './resource'},

{from: './app/public/img/favicon.ico', to: './'},*/

];

let copyArr = [];

copyObj.map((data) => {

copyArr.push(

new CopyWebpackPlugin([{from: data.from, to: data.to, ignore: ['.*']}])

)

});

module.exports = {

devDirectory:'build', /*开发目录*/

   proDirectory:'pc', /*发布目录*/

   resource:'resource', /*静态资源*/

   resourcePrefix:'/static/pc/', /*线上静态资源前缀*/

   cleanFun:cleanFun,

   copyArr: copyArr,

   copyObj: copyObj

};

7.新建 webpack.devBuildHtml.conf.js

const fs =require("fs");

const nodeCommon =require("../common/nodeCommon");

const webpackFile =require("./webpack.file.conf");

const entryBuild =require('../entry/entry');

const webpackComConf =require('./webpack.com.conf');

/*删除构建目录*/

nodeCommon.deleteFile(webpackFile.devDirectory);

/*创建构建目录*/

fs.mkdirSync(webpackFile.devDirectory);

webpackFile.copyObj.map((data) => {

let to =webpackFile.devDirectory + data.to.substring(1, data.to.length);

   if (data.to !=='./') {

fs.mkdirSync(to);

   }

nodeCommon.copyFile(data.from, to);

});

/*生成HTML*/

let htmlCont = fs.readFileSync("index.html", "utf-8");

let scriptInsert =`

`;

htmlCont = htmlCont.replace('', scriptInsert +'');

entryBuild.map((data) => {

fs.writeFile(webpackFile.devDirectory +'/' + data.name +'.html',

       htmlCont.replace('js/key.js', 'js/' + data.name +'.js').replace('<%= htmlWebpackPlugin.options.title %>', webpackComConf.titleFun(data.name,data.title)),

       'utf8',

       function (err) {

if (err) {

return console.log(err);

           }

});

});

8.修改package.json

"devBuildHtml": "node config/webpack/webpack.devBuildHtml.conf.js",

我们删除 根目录下的 build 文件夹,然后执行

npm run devBuildHtml

看下是否自动生成了 build 文件夹 和 index.html shop.html 文件

9.添加 webpack.entry.conf.js

const entryBuild =require('../entry/entry');

let entry = {};

entryBuild.map((data) => {

entry[data.name] = ['./entryBuild/' + data.name +'.js', data.title];

});

module.exports = entry;

10.改造webpack.base.conf.js   统一入口文件

const entry =require("./webpack.entry.conf");

const json =require('../../package.json');//引进package.json

const newEntry = {};

for (let namein entry) {

newEntry[name] = entry[name][0]

}

newEntry.vendor = Object.keys(json.dependencies); //把 package.json dependencies字段的值放进 vendor中

let config = {

entry: newEntry,

   resolve: {

extensions: [".js", ".json", ".jsx", ".css", ".pcss"],

   }

};

module.exports = config;

11.运行

npm run dev

一切OK

12.再往前走一步

修改 package.json

"devNew": "npm run entry && npm run devBuildHtml",

以后我们再有新页面,只需要在 configentryentry.js中添加就可以了

(目前 关键词,描述, 我们有去实现,也好实现,只是我们现在不太关注SEO,我只是预留了这个功能)

图片 3

然后 我们只需要

有新页面的时候执行

npmrun devNew

再执行

npmrun dev

愉快的开发吧~~

本文完

图片 4

禁止擅自转载,如需转载请在公众号中留言联系我们!

感谢童鞋们支持!

欢迎童鞋们留言!

编辑:编程 本文来源:服务器可以监听客户端的请求,也敬请期待我们

关键词: