nodejs留言板的一些总结

本文介绍了Node.js中URL编码的重要性及其应用场景,并详细探讨了如何使用Mongoose对嵌套文档和数组进行精确更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

url编码
  • 在nodejs访问url中有中文时,要用全局函数encodeURIComponent(string) 对其进行编码, (html的链接或提交表action地址中没有这个需求),如http://localhost:3000/小明/家乡 这个链接中,为/:name/:title格式,在nodejs中就如要做如下处理。如果如做处理,则在IE浏览器中会有问题:“TypeError: The header content contains invalid characters”:
var reUrl = 'http://localhost:3000/' + encodeURIComponent(req.params.name) + '/' + encodeURIComponent(title);
res.redirect(reUrl);
ejs模板
  • 传值给ejs模板时,在render函数里处理:
res.render('index',{
    title:"主页",
    user:req.session.user,
    posts:doc
});

// ejs使用时如:

<%if(user){%>
    <%= user.name%>
<%}%>
  • <%= value%>与<%- value%>区别:
    后者会对value的进行javascript语法解析;如 {value:<b>主页<b/>}; --> <%- value%> 这种情况下,value显示的是加粗的主页两字;
mongoose
  • 对子文档或子数组的update方法
    参考资料
    对于数组里的成员更新,在查找条件里仙进行精确定位,再通过$set方法来更新指定的数据,更新的成员前要加上.$.符号,,如下例子:
booksSchema = new Schema({
    name:String,
    price:String,
    keywords:[String]
})
ReaderSchema = new Schema({
    name:String,
    age:Number,
    books:[boosSchema]
})

这里的booksSchema是书的信息,在Reader人数据结构里,数据库中,booksSchema和ReaderSchema一样有_id属性,如{"_id": "0000", "name": "xx", "age": 20, "books":[{"name": "小明", "price":50, "_id": "0001", "keywords":["science"]}]}

更新的时候如下,更新的是”小明“这本书的keywords数组:

readerModel.update({name:"xxx","books.name":"小明"}, {$set:{"books.$.keywords":["biology"]}},function(err){
    //....
})
  • mongoose对于嵌套数据结构的更新处理示例如下所示:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// 对于要存储的结构需要定义
functon Doc(title,id,name,doc){
    this.title = title;
    this.id = id;
    this.name = name;
    this.doc = doc;
}
function Comment(rname,rtime,rcontent){
    this.rName = rname;
    this.rTime = rtime;
    this.rContent = rcontent;
    this.rSubcomments = [];  // 初始化为空
}

// 评论下的回复Schema
var subcommentScema = new Schema({
    srName:String,
    rLvl:String,
    srData:String
});

// 评论的schema
var commentSchema = new Schema({
    rName:String,
    rTime:String,
    rContent:String,
    rSubcomments:[subcommentSchema],
});

var docSchema = new Schema({
    title:String,
    id:Number,
    name:String,
    doc:String,
    comments:[commentSchema]
});

var docsColl = mongoose.model('docs');

var monDb_con = function(callback){
    mongoose.connect('mongodb://host:port/dbname',function(err){
        if(err) throw err;
        else callback(err);
    });
}

var monDb_discon = function(){apparently equivalent
    mongoose.disconnect();
}

// 在主题下面回复,直接保存的doc的comments数组下面
// 调用$push方法来往comments数组添加数据;
Comment.prototype.save = function(callback){
    // 获取文档的title,id
    var com = this;
    monDb_con(function(){
        docsColl.update({id:id},{$push:{comments:{rName:com.rName, rTime:com.rTime, rContent:com.rContent,rSubcomments:[]}},function(err){
            if(err) callback(err);
            else callback(null);
            monDb_discon();
        }}
    });
}


// 在评论下面回复,保存回复到数据空指定的评论下面,保存为数组comments下面的数组rSubcomments
// 下面的rData为subcommentScema对应的结构对象
Doc.prototype.saveSubcomment = function(id,rData,callback){
    monDb_con(function(){
        docsColl.findOne({id:id},{},function(err,doc){
            if(err) callback(err);
            else{
                callback(null);
                // 更新评论里的回复
                var subcom = doc.comments[rData.lvl].subcomments;  // rData.lvl为在第lvl个评论下(0开始算)的回复
                subcom.push(rData);
                doc.save();   // 需要保存
            }
            monDb_discon();
        }
    };
}
RegExp

参考资料
如代码:

str.match(/\?/);  // 查找?
ajax
  • window浏览器兼容:
var xhr = window.ActiveXObject? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest();

如果需要在url后面添加参数,则可能需要对url最后一个/符号进行处理,因为windows不会自动不上/而chrome会加上, 所以如果做如下处理:loaltion.toString()+"?p=1", 则chrome不会在?添加上/, 而windows会添加,所以后能出现两条线//的情况,所以需要处理:

var pUrl = localtion.toString();
if(pUrl[pUrl.length-1]=='/') pUrl = pUrl.slice(0,pUrl.length-1);
  • next()函数

    It passes control to the next matching route. 参考资料

    • 也就是说对于所求路劲的处理,如果调用了next则会将控制权转移到下一个匹配的中间件去处理,如上面链接里的例子。
    • 可用于条件判断,如当条件不满足如没有登陆时,则无法访问指定页面;
  • 发送数据

    1. open函数里可以添加参数,如下例所示,在服务器端就可以通过req.query.p来获取p的值;
    2. 发送数据前,对于对象类型,可以通过JSON.stringify()来转换为字符串, 前面加上键名,这样可以在服务器端通过JSON.parse(req.body.postData)来获得解析对象;
xhr.open("post",pUrl+"?p=true",true)
var postData = {};
postData.name = "heli";
postData.data = "......";
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadstatechange = function(){
    if(xhr.readystate==4 && xhr.status==200){
        console.log(xhr.responseText);
        //location.reload();  // 重载页面
    }
}
xhr.send("postData="+JSON.stringify(postData));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值