Current Situation: Redundant
In web development, do we often use different programming languages to implement the same functionality?
For example, a file upload function requires file format restrictions on the uploaded files. We usually use suffix names for restrictions.
Front end
For the sake of user experience, the file selected by the user will be judged on the page and only if it is legal will the user be able to upload it.
function is_filetype(filename, types) {
types = types.split(',');
var pattern = '.(';
for(var i=0; iif(0 != i) {
pattern = '|';
}
pattern = types[i].trim();
}
pattern = ')$';
return new RegExp(pattern , 'i').test(filename);
};
// Omit N lines of code here
if(!is_filetype($('#uploadfile').val(), 'doc,pdf,txt,wps,odf,md,png,gif,jpg')){
can_submit = false; // Uploading is not allowed
$('#uploadfile').val('') ;
alert('Only upload allowed: ' constant.RESUME_FILETYPES);
}
// N lines of code are omitted here
Backend
due to concerns about malicious uploads , it is inevitable to re-judge the files uploaded by users. So I used python to write a logic to determine the file suffix
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
# Omit N lines here Code
What is the reason for such duplication of work?
1. The front-end can never be trusted;
2. The front-end and back-end use different programming languages;
What is the cost of such redundancy?
1. Modify the business logic and need to repeat it twice: if you suddenly find that the docx file type is not supported, you need to modify the javascript code and python code at the same time
2. Increase the cost of ensuring that the business logic of the javascript code and python code is consistent . Two types of tests need to be written separately, and the unit test runs twice as long.
nodejs era: DRY
Use nodejs no more DRY !
One code, front-end and back-end running at the same time
// 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){
/**
* Remove whitespace characters at both ends of the string
*
* @return {String}
* @api public
*/
String.prototype.trim = function(){
return this.replace(/(^s*) |(s*$)/g, "");
};
/**
* Determine whether the file is of a custom type
*
* @param {String}filename
* @param {String}types, multiple types are separated by a comma, such as 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; iif(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;
}
})() );
Front-end
// Omit N lines of code here
if (!util.is_filetype($('#uploadfile').val(), constant.RESUME_FILETYPES)){
can_submit = false; // Uploading is not allowed
$('#uploadfile').val(' ');
alert('Only uploads allowed: ' constant.RESUME_FILETYPES);
}
// N lines of code are omitted here
Backend
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)) {
// Since the client has made a judgment, this situation is maliciously uploaded. Directly prompt
res.send('File format error: ' filepath
' , please Upload files in ' constant.RESUME_FILETYPES ' format');
return;
}
// save file ...
// N lines of code are omitted here
});
});
Wow, no more redundancy! done
Other common scenarios
Constant definition
Various useful tool modules, such as string operations