nodejs 后綴名判斷限制代碼
更新時(shí)間:2011年03月31日 00:58:43 作者:
如一個(gè)文件上傳功能,需要對(duì)上傳文件進(jìn)行文件格式限制。我們通常會(huì)使用后綴名做限制。
現(xiàn)狀: 冗余
在web開(kāi)發(fā)中,我們是否常常會(huì)使用不同的編程語(yǔ)言實(shí)現(xiàn)相同的功能?
如一個(gè)文件上傳功能,需要對(duì)上傳文件進(jìn)行文件格式限制。我們通常會(huì)使用后綴名做限制。
前端
為了用戶(hù)體驗(yàn),會(huì)在頁(yè)面對(duì)用戶(hù)選擇的文件進(jìn)行判斷,合法才讓用戶(hù)可以上傳。
function is_filetype(filename, types) {
types = types.split(',');
var pattern = '\.(';
for(var i=0; i<types.length; i++) {
if(0 != i) {
pattern += '|';
}
pattern += types[i].trim();
}
pattern += ')$';
return new RegExp(pattern, 'i').test(filename);
};
// 此處省略N行代碼
if(!is_filetype($('#uploadfile').val(), 'doc,pdf,txt,wps,odf,md,png,gif,jpg')){
can_submit = false; // 不允許上傳
$('#uploadfile').val('');
alert('只允許上傳: ' + constant.RESUME_FILETYPES);
}
// 此處省略N行代碼
后端
由于擔(dān)心惡意上傳,無(wú)法避免地需要重新對(duì)用戶(hù)上傳的文件進(jìn)行判斷。于是我又用python寫(xiě)了一個(gè)判斷文件后綴的邏輯
import re
def is_filetype(filename, types):
types = types.split(',')
pattern = '\.(' + '|'.join([t.strip() for t in types]) + ')$';
return re.search(pattern, filename, re.I) != None
# web request handler
# 此處省略N行代碼
導(dǎo)致這樣重復(fù)工作的原因是為什么?
1.前端永遠(yuǎn)不可信;
2.前端和后端使用不同的編程語(yǔ)言;
這樣的冗余會(huì)帶來(lái)什么代價(jià)?
1.修改業(yè)務(wù)邏輯,需要重復(fù)做2次:如突然發(fā)現(xiàn)少支持了 docx 文件類(lèi)型,需要同時(shí)修改javascript代碼和python代碼
2.增加確保javascript代碼和python代碼業(yè)務(wù)邏輯一致的代價(jià)。需要分別寫(xiě)2種測(cè)試,unit test跑多一倍。
nodejs時(shí)代:DRY
一份代碼,前端后端同時(shí)運(yùn)行
// constant.js
(function(exports){
exports.RESUME_FILETYPES = 'doc,docx,pdf,txt,wps,odf,md,png,gif,jpg';
})( (function(){
if(typeof exports === 'undefined') {
window.constant = {};
return window.constant;
} else {
return exports;
}
})() );
// util.js
(function(exports){
/**
* 移除字符串兩端的空白字符
*
* @return {String}
* @api public
*/
String.prototype.trim = function(){
return this.replace(/(^\s*)|(\s*$)/g, "");
};
/**
* 判斷是否自定類(lèi)型的文件
*
* @param {String}filename
* @param {String}types, 多個(gè)類(lèi)型使用,號(hào)分隔,如 doc,docx,txt
* @return {Boolean} true or false
* @api public
*/
var is_filetype = exports.is_filetype = function(filename, types) {
types = types.split(',');
var pattern = '\.(';
for(var i=0; i<types.length; i++) {
if(0 != i) {
pattern += '|';
}
pattern += types[i].trim();
}
pattern += ')$';
return new RegExp(pattern, 'i').test(filename);
};
})( (function(){
if(typeof exports === 'undefined') {
window.util = {};
return window.util;
} else {
return exports;
}
})() );
前端
<script src="/js/util.js"></script>
<script src="/js/constant.js"></script>
// 此處省略N行代碼
if(!util.is_filetype($('#uploadfile').val(), constant.RESUME_FILETYPES)){
can_submit = false; // 不允許上傳
$('#uploadfile').val('');
alert('只允許上傳: ' + constant.RESUME_FILETYPES);
}
// 此處省略N行代碼
后端
var util = require('./public/js/util.js'),
constant = require('./public/js/constant.js');
app.post('/resume/upload/:job_id', function(req, res, next){
req.form.complete(function(err, fields, files){
if(!util.is_filetype(filepath, constant.RESUME_FILETYPES)) {
// 由于客戶(hù)端已做判斷,所以這樣的情況都是惡意上傳的,直接提示
res.send('文件格式錯(cuò)誤: ' + filepath
+ ' , 請(qǐng)上傳' + constant.RESUME_FILETYPES + '格式的文件');
return;
}
// save file ...
// 此處省略N行代碼
});
});
wow,沒(méi)冗余了吧!done
其他常用場(chǎng)景
常量定義
各種有用的工具模塊,如字符串操作
在web開(kāi)發(fā)中,我們是否常常會(huì)使用不同的編程語(yǔ)言實(shí)現(xiàn)相同的功能?
如一個(gè)文件上傳功能,需要對(duì)上傳文件進(jìn)行文件格式限制。我們通常會(huì)使用后綴名做限制。
前端
為了用戶(hù)體驗(yàn),會(huì)在頁(yè)面對(duì)用戶(hù)選擇的文件進(jìn)行判斷,合法才讓用戶(hù)可以上傳。
復(fù)制代碼 代碼如下:
function is_filetype(filename, types) {
types = types.split(',');
var pattern = '\.(';
for(var i=0; i<types.length; i++) {
if(0 != i) {
pattern += '|';
}
pattern += types[i].trim();
}
pattern += ')$';
return new RegExp(pattern, 'i').test(filename);
};
// 此處省略N行代碼
if(!is_filetype($('#uploadfile').val(), 'doc,pdf,txt,wps,odf,md,png,gif,jpg')){
can_submit = false; // 不允許上傳
$('#uploadfile').val('');
alert('只允許上傳: ' + constant.RESUME_FILETYPES);
}
// 此處省略N行代碼
后端
由于擔(dān)心惡意上傳,無(wú)法避免地需要重新對(duì)用戶(hù)上傳的文件進(jìn)行判斷。于是我又用python寫(xiě)了一個(gè)判斷文件后綴的邏輯
復(fù)制代碼 代碼如下:
import re
def is_filetype(filename, types):
types = types.split(',')
pattern = '\.(' + '|'.join([t.strip() for t in types]) + ')$';
return re.search(pattern, filename, re.I) != None
# web request handler
# 此處省略N行代碼
導(dǎo)致這樣重復(fù)工作的原因是為什么?
1.前端永遠(yuǎn)不可信;
2.前端和后端使用不同的編程語(yǔ)言;
這樣的冗余會(huì)帶來(lái)什么代價(jià)?
1.修改業(yè)務(wù)邏輯,需要重復(fù)做2次:如突然發(fā)現(xiàn)少支持了 docx 文件類(lèi)型,需要同時(shí)修改javascript代碼和python代碼
2.增加確保javascript代碼和python代碼業(yè)務(wù)邏輯一致的代價(jià)。需要分別寫(xiě)2種測(cè)試,unit test跑多一倍。
nodejs時(shí)代:DRY
一份代碼,前端后端同時(shí)運(yùn)行
復(fù)制代碼 代碼如下:
// constant.js
(function(exports){
exports.RESUME_FILETYPES = 'doc,docx,pdf,txt,wps,odf,md,png,gif,jpg';
})( (function(){
if(typeof exports === 'undefined') {
window.constant = {};
return window.constant;
} else {
return exports;
}
})() );
// util.js
(function(exports){
/**
* 移除字符串兩端的空白字符
*
* @return {String}
* @api public
*/
String.prototype.trim = function(){
return this.replace(/(^\s*)|(\s*$)/g, "");
};
/**
* 判斷是否自定類(lèi)型的文件
*
* @param {String}filename
* @param {String}types, 多個(gè)類(lèi)型使用,號(hào)分隔,如 doc,docx,txt
* @return {Boolean} true or false
* @api public
*/
var is_filetype = exports.is_filetype = function(filename, types) {
types = types.split(',');
var pattern = '\.(';
for(var i=0; i<types.length; i++) {
if(0 != i) {
pattern += '|';
}
pattern += types[i].trim();
}
pattern += ')$';
return new RegExp(pattern, 'i').test(filename);
};
})( (function(){
if(typeof exports === 'undefined') {
window.util = {};
return window.util;
} else {
return exports;
}
})() );
前端
復(fù)制代碼 代碼如下:
<script src="/js/util.js"></script>
<script src="/js/constant.js"></script>
// 此處省略N行代碼
if(!util.is_filetype($('#uploadfile').val(), constant.RESUME_FILETYPES)){
can_submit = false; // 不允許上傳
$('#uploadfile').val('');
alert('只允許上傳: ' + constant.RESUME_FILETYPES);
}
// 此處省略N行代碼
后端
復(fù)制代碼 代碼如下:
var util = require('./public/js/util.js'),
constant = require('./public/js/constant.js');
app.post('/resume/upload/:job_id', function(req, res, next){
req.form.complete(function(err, fields, files){
if(!util.is_filetype(filepath, constant.RESUME_FILETYPES)) {
// 由于客戶(hù)端已做判斷,所以這樣的情況都是惡意上傳的,直接提示
res.send('文件格式錯(cuò)誤: ' + filepath
+ ' , 請(qǐng)上傳' + constant.RESUME_FILETYPES + '格式的文件');
return;
}
// save file ...
// 此處省略N行代碼
});
});
wow,沒(méi)冗余了吧!done
其他常用場(chǎng)景
常量定義
各種有用的工具模塊,如字符串操作
您可能感興趣的文章:
相關(guān)文章
小程序開(kāi)發(fā)基礎(chǔ)之view視圖容器
這篇文章主要介紹了小程序開(kāi)發(fā)基礎(chǔ)之view視圖容器,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
JS實(shí)現(xiàn)兩表格里數(shù)據(jù)來(lái)回轉(zhuǎn)移的方法
這篇文章主要介紹了JS實(shí)現(xiàn)兩表格里數(shù)據(jù)來(lái)回轉(zhuǎn)移的方法,涉及javascript鼠標(biāo)事件及頁(yè)面元素的相關(guān)操作技巧,需要的朋友可以參考下2015-05-05
JavaScript實(shí)現(xiàn)H5接金幣功能(實(shí)例代碼)
這篇文章主要介紹了JavaScript實(shí)現(xiàn)H5接金幣功能,本文分步驟通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
用原生JS對(duì)AJAX做簡(jiǎn)單封裝的實(shí)例代碼
下面小編就為大家?guī)?lái)一篇用原生JS對(duì)AJAX做簡(jiǎn)單封裝的實(shí)例代碼。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07
基于JavaScript實(shí)現(xiàn)瀑布流布局(二)
這篇文章主要介紹了原生JavaScript實(shí)現(xiàn)瀑布流布局的相關(guān)資料,實(shí)現(xiàn)鼠標(biāo)下拉圖片自動(dòng)加載效果,和百度圖片效果類(lèi)似,需要的朋友可以參考下2016-01-01

