一、web服务器示例
var http = require('http');
http.createServer(function(req, res){
res.writeHeader(200, {Content-Type : 'text/plain'});
res.end('hello world!');
}).listen(80);
二、web应用中常见需求:
(1)解析请求方法(POST GET)
(2)解析路径
(3)解析查询字符串
(4)解析cookie
(5)Basic认证
(6)解析表单数据
(7)文件上传
 
三、解析请求方法
function(req, res){
var method = req.method;
if(method === 'POST'){
}else if(method === 'GET'){
}else if(method === 'DELETE'){
}else if(method === 'PUT'){
}else{
}
}
四、解析路径
(1)返回静态资源
var url = require('url');
var fs = require('fs');
function(req, res){
var pathname = url.parse(req.url).pathname;
fs.readFile(path.join(ROOT, pathname), function(err, file){
if(err){
res.writeHeader(404);
res.end('not Found File');
return;
}
res.writeHeader(200);
res.end(file);
});
}
 
(2)选择控制器:/controller/action/a/b/c
function(req, res){
var pathname = url.parse(req.url).pathname;
var paths = pathname.split('/');
var contronller = paths[1] || 'index';
var action = paths[2] || 'index';
var args = paths.slice(3);
if(handler[contronller] && handler[contronller][action]){
handler[contronller][action].apply(null, [req, res].concat(args));
}else{
res.writeHeader(500);
res.end('找不到响应控制器');
}
}
四、查询字符串
var url = require('url');
var query = url.parse(req.url, true).query;//{foo : 'aaa', baz : 'bbb'}
req.query = query;
handle(req, res);
五、cookie
function parseCookie(cookie){
var cookies = {};
if(!cookie){
return cookies;
}
var list = cookie.split(';');
for(var i = 0,len = list.length;i < len;i++){
var pair = list[i].split('=');
cookies[pair[0].trim()] = pair[1];
}
return cookies;
};
req.cookies = parseCookie(req.headers.cookie);
handle(req, res); function serialize(name, value, options){
var pairs = [name+'='+value];
if(options.expires){
pairs.push('Expires='+options.expires.toUTCString());
}
if(options.maxAge){
pairs.push('Max-Age='+options.maxAge);
}
if(options.path){
pairs.push('Path='+options.path);
}
if(options.domain){
pairs.push('Domain='+options.domain);
}
if(options.httpOnly){
pairs.push('HTTPOnly');
}
if(options.secure){
pairs.push('Secure');
}
return pares.join(';');
} res.writeHeader('Set-Cookie', serialize({isVisit : 1}));
六、Session
Cookie缺点:
(1)可在前端改变cookie的值(HTTPOnly可限制前端改变cookie),易篡改。
(2)隐私信息无法存cookie
(3)占用网络带宽(每次请求,相关path下的cookie信息都会在请求头中携带,虽然服务端有时候并不需要所有的cookie信息)
基于以上缺点,敏感信息必须从Session获取。
在服务端为Session生成一个键值,将该键值写入Cookie,用户凭借键值获取自己的session 用于解决http协议无状态缺陷,维护用户状态。
 
七、数据上传
var hasBody = function(req){
return 'transfer-encoding' in req.Headers || 'content-length' in req.Headers;
} function(req, res){
if(hasBody(req)){
var buffers = [];
req.on('data', function(chunk){
buffers.push(chunk);
});
req.on('end', function(){
req.rawBody = Buffer.concat(buffers).toString();
handle(req, res);
});
}else{
handle(req, res);
}
};
业务中可以判断conten-type 采用不同的方式解析req.rawBody
x-www-form-urlencoded:
req.body = querystring.parse(req.rawBody);

var mime = function(req){
return req.headers['content-type'].split(';')[0] || '';
} var xml2js = require('xml2js');
var handle = function(req, res){
if(mime(req) === 'application/json'){
try{
req.body = JSON.parse(req.rowBody);
}catch(){
res.writeHeader('400');
res.end('invalid json');
return;
}
}
if(mime(req) === 'application/xml'){
xml2js.parseString(req,rawBody, function(err, xml){
if(err){
}else{
req.body = xml;
}
});
}
};
附件上传:
content-type : multipart/form-data
var formidable = require('formidable');
function(req, res){
if(hasBody(req)){
if(mime(req) === 'multipart/form-data'){
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files){
req.body = fields;
req.files = files;
handle(req, res);
});
}
}
}
八、数据上传与安全
在解析表单,JSON和XML的过程中,如果用户提交的数据量较大,不能直接读入内存。避免内存耗尽的情况发生。一般解决这种问题有以下两种方案:
(1)、限制上传内容的大小,超过大小直接返回400状态码
(2)、流式解析,将数据导向磁盘中,Node中只保留文件路径。
如下为Connect中采用的上传数据量的限制方式:
var bytes = 1024;

function(req, res){
var received = 0;
var len = req.headers['content-length']?parseInt(req.headers['content-length'], 10):null;
if(len > bytes){
res.writeHeader(413);
res.end;
return;
} res.on('data', function(chunk){
received += chunk.length;
if(received > bytes){
req.destroy();
}
}); handle(req, res);
};
 
CSRF 跨站消息伪造
防御方法:服务端生成随机数,将该随机数告知前端,前端在请求中携带该随机数。没有携带制定规则随机数的请求服务端一律不处理。
 
九、附件下载
设置响应头Content-Disposition : attachment;filename="fdfd.txt"
 

构建web应用的更多相关文章

  1. NodeJs+http+fs+request+cheerio 采集,保存数据,并在网页上展示(构建web服务器)

    目的: 数据采集 写入本地文件备份 构建web服务器 将文件读取到网页中进行展示 目录结构: package.json文件中的内容与上一篇一样:NodeJs+Request+Cheerio 采集数据 ...

  2. 使用EXtjs6.2构建web项目

    一.项目简介 众所周知ext是一款非常强大的表格控件,尤其是里边的grid为用户提供了非常多的功能,现在主流的还是用extjs4.0-4.2,但是更高一点的版本更加符合人的审美要求.因此,在今天咱们构 ...

  3. 《深入浅出Node.js》第8章 构建Web应用

    @by Ruth92(转载请注明出处) 第8章 构建Web应用 一.基础功能 请求方法:GET.POST.HEAD.DELETE.PUT.CONNECT GET /path?foo=bar HTTP/ ...

  4. 基于MVC4+EasyUI的Web开发框架经验总结(2)- 使用EasyUI的树控件构建Web界面

    最近花了不少时间在重构和进一步提炼我的Web开发框架上,力求在用户体验和界面设计方面,和Winform开发框架保持一致,而在Web上,我主要采用EasyUI的前端界面处理技术,走MVC的技术路线,在重 ...

  5. Eclipse中使用maven构建web项目中遇到的问题

    构建过程参考: http://blog.csdn.net/smilevt/article/details/8215558/ http://www.cnblogs.com/dcba1112/archiv ...

  6. Node.js高级编程读书笔记 - 4 构建Web应用程序

    Outline 5 构建Web应用程序 5.1 构建和使用HTTP中间件 5.2 用Express.js创建Web应用程序 5.3 使用Socket.IO创建通用的实时Web应用程序 5 构建Web应 ...

  7. 高效构建Web应用 教你玩转Play框架 http://www.anool.net/?p=577

    Play 框架是一个完整的Web应用开发框架,覆盖了Web应用开发的各个方面.Play 框架在设计的时候借鉴了流行的 Ruby on Rails 和 Grails 等框架,又有自己独有的优势.使用 P ...

  8. threejs构建web三维视图入门教程

    本文是一篇简单的webGL+threejs构建web三维视图的入门教程,你可以了解到利用threejs创建简单的三维图形,并且控制图形运动.若有不足,欢迎指出. 本文使用的框架是three.js gi ...

  9. axis2_1.6.2之构建web端和客户端 .

    参考资料: http://blog.csdn.net/apei830/article/details/5448897 axis2的官网 http://axis.apache.org/axis2/jav ...

  10. 使用XFire+Spring构建Web Service(一)——helloWorld篇

    转自:http://www.blogjava.net/amigoxie/archive/2007/09/26/148207.html原文出处:http://tech.it168.com/j/2007- ...

随机推荐

  1. 第一次接触C++------感触

    2018/09/24 上大学第一次接触C++,感觉还挺有趣的. C语言是计算机的一门语言,顾名思义,语言嘛,有它自己独特的语法. 第一次用C++敲代码,觉得还挺不错的,可以从中找到乐趣.咏梅老师布置的 ...

  2. Java与其它语言的比较

    Java与C/C++相比.Java语言是一种完全的面对对象语言,虽然他的底层(运行时库)是用C语言开发 的,可是并不依赖于C.因为Java的运行是在运行时库的支持下运行的,所以运行的效率比起可以更接近 ...

  3. 平衡树学习笔记(5)-------SBT

    SBT 上一篇:平衡树学习笔记(4)-------替罪羊树 所谓SBT,就是Size Balanced Tree 它的速度很快,完全碾爆Treap,Splay等平衡树,而且代码简洁易懂 尤其是插入节点 ...

  4. 树链剖分【洛谷P3833】 [SHOI2012]魔法树

    P3833 [SHOI2012]魔法树 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节 ...

  5. kuangbin专题十二 HDU1087 Super Jumping! Jumping! Jumping! (LIS)

    Super Jumping! Jumping! Jumping! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 ...

  6. react 什么是虚拟DOM?深入了解虚拟DOM

    底层的理论基础 一. 原始生成步骤 1.state 数据 2.jsx 模版 3.数据 + 模板 结合,生成真实的DOM,来显示 4.state 发生改变了 5.数据 + 模板 结合,生成真实的DOM, ...

  7. react 部分语法补充

    jsx语法 todolist.js import React, { Component,Fragment } from 'react'; import './style.css' class Todo ...

  8. BZOJ 3083 遥远的国度 树链剖分+脑子

    唉..又调了半天QWQ..为何读入挂了.....莫非读入是反着的????据ywy学长所言如是...OvO震惊 这啥骚题啊...还要换根...不过清明讲过...(然鹅我现在才做... 先随便选个点(比如 ...

  9. Codeforces Round #532 (Div. 2)- C(公式计算)

    NN is an experienced internet user and that means he spends a lot of time on the social media. Once ...

  10. 互联网开发-web文件上传性能问题

    1. 问题描述 文件大小 部署环境 平均上传速度 5M 外网 28s-36s 5M 公司局域内网 秒传,很快 2. 问题分析 在网上搜索“测速网”测试了一下公司外网的带宽情况: 上传带宽 = 1.04 ...