构建web应用

一、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应用,布布扣,bubuko.com

时间: 2024-12-03 11:22:45

构建web应用的相关文章

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

最近花了不少时间在重构和进一步提炼我的Web开发框架上,力求在用户体验和界面设计方面,和Winform开发框架保持一致,而在Web上,我主要采用EasyUI的前端界面处理技术,走MVC的技术路线,在重构完善过程中,很多细节花费不少时间进行研究和提炼,一步步走过来,也积累了不少经验,本系列将主要介绍我在进一步完善我的Web框架基础上积累的经验进行分享,本随笔主要介绍使用EasyUI的树控件构建Web界面的相关经验. 在很多界面设计上,我们可能都需要引入树列表控件,这个控件可以用zTree来实现,也

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

本文是一篇简单的webGL+threejs构建web三维视图的入门教程,你可以了解到利用threejs创建简单的三维图形,并且控制图形运动.若有不足,欢迎指出. 一.创建场景我们所见的视图由两个部分共同创建,scene和camera.首先定义一个场景:var scene = new THREE.Scene();然后定义一个相机:var camera = new THREE.PerspectiveCamera( 90, width/height, 0.1, 1000 );等等,定义相机需要视窗的长

利用Eclipse中的Maven构建Web项目(一)

利用Eclipse中的Maven构建Web项目 1.新建一个Maven Project,"New-->Other..." 2.选择"Maven Project" 3.选择项目路径 Usedefault Workspace location默认工作空间, 选择项目类型 在Artifact Id中选择maven-archetype-webapp 4.分别输入Group Id.Artifact Id和Package,单击"Finish" 5.Ma

利用Eclipse中的Maven构建Web项目(二)

利用Eclipse中的Maven构建Web项目 1.新建源文件夹,Java Resources鼠标右键,"New-->Source Folder" 2.新建src/main/java   src/main/resources  src/test/java  src/test/resources四个源包 3.双击每个文件夹的Output folder,选择路径 src/main/java和src/main/resources,选择路径target/classes; src/test

Maven构建Web工程项目报错

利用Maven构建Web项目的时候项目报错,pom.xml报错 先右键Maven-Disable Maven Nature,关闭Maven属性 然后再点击Configure-Convert To Maven Project 然后就能消除错误

Eclipse使用Maven构建web项目

Eclipse使用Maven构建web项目 博客分类: J2EE 1.创建Maven项目: 点击“File”菜单,或者通过工具栏的“New”创建Project,如下图所示: 选择Maven->Maven Project,弹出向导对话框,如下图所示: 选中Create a simple project……复选框,其它的设置不变,并点击Next,输入maven项目必须的信息(groupId,artifactid,version),如下图所示: 这里需要选择Packaging,web项目一般选择war

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

最近花了不少时间在重构和进一步提炼我的Web开发框架上,力求在用户体验和界面设计方面,和Winform开发框架保持一致,而在Web上,我主要采用EasyUI的前端界面处理技术,走MVC的技术路线,在重构完善过程中,很多细节花费不少时间进行研究和提炼,一步步走过来,也积累了不少经验,本系列将主要介绍我在进一步完善我的Web框架基础上积累的经验进行分享,本随笔主要介绍使用EasyUI的树控件构建Web界面的相关经验. 在很多界面设计上,我们可能都需要引入树列表控件,这个控件可以用zTree来实现,也

利用Eclipse中的Maven构建Web项目(三)

利用Eclipse中的Maven构建Web项目 1.将Maven Project转换成动态Web项目,鼠标右键项目,输入"Project Facets" 2.根据Dynamic Web Module的版本修改Java Compiler中的"Compiler compliance level"的版本 3.设置部署程序集(Web Deployment Assembly),删除含有"test" 4.将Maven的jar包发布到lib下, "A

利用Eclipse中的Maven构建Web项目报错

利用Eclipse中的Maven构建Web项目 1.在进行上述操作时,pom.xml一直报错 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.o