Node与Express开发:6 7 8 章

电子书:http://download.csdn.net/download/qfire/10232839

代码:https://i-blog.csdnimg.cn/blog_migrate/8b1d01c3d2170aa3f6fd988903bea78c.png

第六章 请求和响应   

     除了请求报头外,请求还有一个主体(就像作为实际内容返回的响应主题一样)。一般GET请求没有主题内容,但POST请求是有的。POST请求体最常见的媒体类型是application/x-www-form-urlendcoded,是键值对集合的简单编码,用&分隔(基本上和查询字符串的格式一样)。如果POST请求需要支持文件上传,则媒体类型是multipart/form-data,它是一种更为复杂的格式,最后是AJAX请求,它可以使用application/json。

第七章 Handlebars模板引擎

    在Node中,有许多模板引擎可供选择。Veena Basavaraj的文章关于她为LinkedIn选择模板引擎时的相关准则。

    https://engineering.linkedin.com/frontend/client-side-templating-throwdown-mustache-handlebars-dustjs-and-more

    理解模板引擎的关键在于context。当你渲染一个模板时,便会传递给模板引擎一个对象,叫做上下文对象,它能让替换标识运行。

    服务器端模板除了隐藏实现细节,还支持模板缓存,这对性能很重要。

第八章 表单处理

    从用户那里收集信息的常用方法就是使用HTML表单。

    有一种普遍的误解是POST请求是安全的,而GET请求不安全。事实上如果使用HTTPS协议,两者都是安全的;如果不使用,则都不安全。如果不使用HTTPS协议,入侵者会像查看GET请求的查询字符串一样。轻松查看POST请求的报文数据。然而,如果你使用GET请求,用户会在查询字符串中看到所有的输入数据(包括隐藏域),此外,浏览器会限制查询字符串的长度。基于这些原因,一般推荐使用POST进行表单提交。

    注意隐藏域:它不会呈现在浏览器中。但是,你不能使用它存放秘密和敏感信息:用户只要查看页面源文件,隐藏域就会暴露出来。

    发送文件不建议使用Express处理。

    Express表单处理:GET的表单域在req.query对象中,POST需要引入中间件app.use(require('body-parser')()); req.body变为可用。

    $ npm install --save body-parser

var bodyparser = require('body-parser').urlencoded({extended:false});
app.use(bodyparser);
app.get('/newsletter', function(req, res) {
	console.log("newsletter");
	res.render('newsletter', {csrf: "CSRF token goes here" });
});
app.post('/process', function(req, res){
	console.log('Form :' + req.query.form);
	console.log('CSRF token :' + req.body._csrf);
	console.log('Name :' + req.body.name);
	console.log('Email :' + req.body.email);
	//重定向thank-you视图
	res.redirect(303, '/thank-you');
});
   $ subl views/newsletter.handlebars

<h2>Sign up for our newsletter to receive news and specials!</h2>
<form class="form-horizontal" role="form" action="/process?form=newsletter" method="POST">
  <input type="hidden" name="_csrf" value="{{csrf}}">
  <div class="form-group">
     <label for="fieldName" class="col-sm-2 control-label">Name</label>
     <div class="col-sm-4">
       <input type="text" class="form-control" id="fieldName" name="name">
     </div>
  </div>
  <div class="form-group">
     <label for="fieldEmail" class="col-sm-2 control-label">Email</label>
     <div class="col-sm-4">
       <input type="email" class="form-control" id="Email" name="email">
     </div>
  </div>
  <div class="form-group">
     <div class="col-sm-offset-2 col-sm-4">
       <button type="submit" class="btn btn-default">Register</button>
     </div>
  </div>
</form>
      http://localhost:3000/newsletter

      处理AJAX表单

<h2>Sign up for our newsletter to receive news and specials!</h2>
<div class="formContainer">
	<form class="form-horizontal" role="form" action="/process?form=newsletter" method="POST">
	  <input type="hidden" name="_csrf" value="{{csrf}}">
	  <div class="form-group">
	     <label for="fieldName" class="col-sm-2 control-label">Name</label>
	     <div class="col-sm-4">
	       <input type="text" class="form-control" id="fieldName" name="name">
	     </div>
	  </div>
	  <div class="form-group">
	     <label for="fieldEmail" class="col-sm-2 control-label">Email</label>
	     <div class="col-sm-4">
	       <input type="email" class="form-control" id="Email" name="email">
	     </div>
	  </div>
	  <div class="form-group">
	     <div class="col-sm-offset-2 col-sm-4">
	       <button type="submit" class="btn btn-default">Register</button>
	     </div>
	  </div>
	</form>
</div>
{{#section 'jquery'}}
   <script>
      $(document).ready(function(){
        $('.newsletterForm').on('submit', function(evt){
           evt.preventDefault();
           var action = $(this).attr('action');
           var $container = $(this).closest('.formContainer');
           $.ajax({
             url: action,
             type: 'POST',
             success: function(data) {
                if(data.success){
                   $container.html('<h2>Thank you!</h2>');
                } else {
                   $container.html('There was a problem.');
                }
             },
             error: function() {
                $container.html('There was a problem.');
             }
           });
        });
      })
   </script>
{{/section}}
app.post('/process', function(req, res){
	//如果是AJAX,则req.xhr为true
	if (req.xhr || req.accepts('json,html') === 'json') {
		//通常将数据保存到数据库
		res.send({success: true});
	} else {
	    //重定向thank-you视图
	    res.redirect(303, '/thank-you');
	}
});
      文件上传:可以使用Connect的内置中间件multipart处理。但它已经移除。对于复合表单处理,目前有两种流行而健壮的选择:Busboy和Formidable。我们使用Formidable

     $ npm install --save formidable

     $ subl views/contest/vacation-photo.handlebars

<form class="form-horizontal" role="form" enctype="multipart/form-data" method="POST" action="/contest/vacation-photo/{year}/{month}">
  <div class="form-group">
    <label for="fieldName" class="col-sm-2 control-label">Name</label>
	<div class="col-sm-4">
	  <input type="text" class="form-control" id="fieldName" name="name">
	</div>     
  </div>
  <div class="form-group">
	<label for="fieldEmail" class="col-sm-2 control-label">Email</label>
	<div class="col-sm-4">
	  <input type="email" class="form-control" required id="fieldEmail" name="email">
	</div>
  </div>
  <div class="form-group">
	<label for="fieldPhoto" class="col-sm-2 control-label">Vacation</label>
	<div class="col-sm-4">
	  <input type="file" class="form-control" required accept="image/*" id="fieldPhoto" name="photo">
	</div>
  </div>
  <div class="form-group">
     <div class="col-sm-offset-2 col-sm-4">
       <button type="submit" class="btn btn-primary">Submit</button>
     </div>
  </div>
</form
var formidable = require('formidable');
app.get('/contest/vacation-photo', function(req, res){
	var now = new Date();
	res.render('contest/vacation-photo', {
		year: now.getFullYear(), month: now.getMonth()
	});
});
app.post('/contest/vacation-photo/:year/:month', function(req, res){
	var form = new formidable.IncomingForm();
	form.parse(req, function(err, fields, files) {
		if (err) return res.redirect(303, '/error');
		console.log('received fields:');
		console.log(fields);
		console.log('received files:');
		console.log(files);
		res.redirect(303, '/thank-you');
	});
});
    jQuery文件上传:可拖拽、看上传文件缩略图、查看进度条。推荐使用http://blueimp.github.io/jQuery-File-Upload

    安装ImageMagick,文件的存储可以是创建一个时间戳目录来存储文件。更实际的做法是使用用户ID或其他唯一ID来创建子目录。例如,如果实现一个支持文件共享的聊天程序,你可能使用聊天室的ID。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值