mirror of
https://github.com/thinkjs/thinkjs.git
synced 2026-01-25 14:42:47 +00:00
197 lines
6.9 KiB
JavaScript
197 lines
6.9 KiB
JavaScript
/**
|
|
* 检测路由行为
|
|
* 通过自定义路由识别到对应的URL上
|
|
* @return {[type]} [description]
|
|
*/
|
|
var url = require("url");
|
|
var Dispatcher = thinkRequire("Dispatcher");
|
|
|
|
module.exports = Behavior(function(){
|
|
"use strict";
|
|
return {
|
|
options: {
|
|
'url_route_on': false, //是否开启自定义URL路由
|
|
'url_route_rules': [] //自定义URL路由规则
|
|
},
|
|
run: function(){
|
|
if (!this.options.url_route_on) {
|
|
return false;
|
|
}
|
|
var routes = this.options.url_route_rules;
|
|
var length = routes.length;
|
|
if (length === 0) {
|
|
return false;
|
|
}
|
|
var pathname = this.http.pathname;
|
|
var match;
|
|
for(var i = 0; i < length; i++){
|
|
var route = routes[i];
|
|
var rule = route[0];
|
|
//正则路由
|
|
if (rule && isRegexp(rule)) {
|
|
match = pathname.match(rule);
|
|
if (match) {
|
|
var result = this.parseRegExp(match, route[1], pathname);
|
|
if (result) {
|
|
return result;
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
//字符串路由
|
|
match = this.checkUrlMatch(pathname, rule);
|
|
if (match) {
|
|
return this.parseRule(rule, route[1], pathname);
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
/**
|
|
* 解析字符串路由
|
|
* @param {[type]} rule [description]
|
|
* @param {[type]} route [description]
|
|
* @param {[type]} pathname [description]
|
|
* @return {[type]} [description]
|
|
*/
|
|
parseRule: function(rule, route, pathname){
|
|
route = this.getRoute(route);
|
|
if (!route) {
|
|
return false;
|
|
}
|
|
pathname = pathname.split("/").filter(function(item){
|
|
return item.trim();
|
|
});
|
|
rule = rule.split("/").filter(function(item){
|
|
return item.trim();
|
|
});
|
|
var matches = {};
|
|
rule.forEach(function(item){
|
|
var pathitem = pathname.shift();
|
|
if (item.indexOf(":") === 0) {
|
|
matches[item] = pathitem;
|
|
}
|
|
});
|
|
//将剩余的pathname分割为querystring
|
|
if (pathname.length) {
|
|
for(var i = 0,length = Math.ceil(pathname.length)/2; i < length; i++){
|
|
this.http.get[pathname[i * 2]] = pathname[i * 2 + 1] || "";
|
|
}
|
|
}
|
|
var values = Object.values(matches);
|
|
route = route.replace(/:(\d+)/g, function(a, b){
|
|
return values[b - 1] || "";
|
|
});
|
|
this.parseUrl(route);
|
|
return true;
|
|
},
|
|
/**
|
|
* 检测URL是否匹配
|
|
* @param {[type]} pathname [description]
|
|
* @param {[type]} rule [description]
|
|
* @return {[type]} [description]
|
|
*/
|
|
checkUrlMatch: function(pathname, rule){
|
|
pathname = pathname.split("/").filter(function(item){
|
|
return item.trim();
|
|
});
|
|
rule = rule.split("/").filter(function(item){
|
|
return item.trim();
|
|
});
|
|
return rule.every(function(item, i){
|
|
if (item.indexOf(':') === 0) {
|
|
if (item.indexOf('\\') > -1) {
|
|
var type = item.substr(-1);
|
|
if (type === 'd' && !isNumberString(pathname[i])) {
|
|
return false;
|
|
}
|
|
}
|
|
}else{
|
|
var pitem = pathname[i] || "";
|
|
if (pitem.toLowerCase() !== item.toLowerCase()) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
});
|
|
},
|
|
/**
|
|
* 解析转化后的url
|
|
* @param {[type]} urlInfo [description]
|
|
* @return {[type]} [description]
|
|
*/
|
|
parseUrl: function(urlInfo){
|
|
urlInfo = url.parse(urlInfo, true);
|
|
if (urlInfo.query) {
|
|
for(var key in urlInfo.query){
|
|
if (urlInfo.query[key] || !(key in this.http.get)) {
|
|
this.http.get[key] = urlInfo.query[key];
|
|
}
|
|
}
|
|
}
|
|
var pathname = urlInfo.pathname || "";
|
|
// 过滤调用pathname最后有/的情况
|
|
pathname = pathname.split("/").filter(function(item){
|
|
return item.trim();
|
|
});
|
|
this.http.action = Dispatcher.getAction(pathname.pop());
|
|
this.http.controller = Dispatcher.getController(pathname.pop());
|
|
this.http.group = Dispatcher.getGroup(pathname.pop());
|
|
},
|
|
/**
|
|
* 获取route
|
|
* @param {[type]} route [description]
|
|
* @return {[type]} [description]
|
|
*/
|
|
getRoute: function(route){
|
|
if (isFunction(route)) {
|
|
route = route();
|
|
}else if (isObject(route)) {
|
|
var sRoute = "";
|
|
var filter = function(item){
|
|
return item.trim();
|
|
};
|
|
//对应的请求类型
|
|
for(var method in route){
|
|
var nmethod = method.split(",").filter(filter);
|
|
if (nmethod.indexOf(this.http.method) > -1) {
|
|
sRoute = route[method];
|
|
break;
|
|
}
|
|
}
|
|
if (!sRoute) {
|
|
return false;
|
|
}
|
|
route = sRoute;
|
|
}
|
|
return route;
|
|
},
|
|
/**
|
|
* 正则匹配路由
|
|
* @param {[type]} matches [description]
|
|
* @param {[type]} route [description]
|
|
* @param {[type]} pathname [description]
|
|
* @return {[type]} [description]
|
|
*/
|
|
parseRegExp: function(matches, route, pathname){
|
|
route = this.getRoute(route);
|
|
if (!route) {
|
|
return false;
|
|
}
|
|
route = route.replace(/:(\d+)/g, function(a, b){
|
|
return matches[b] || "";
|
|
});
|
|
pathname = pathname.replace(matches[0], "");
|
|
pathname = pathname.split("/").filter(function(item){
|
|
return item;
|
|
});
|
|
//将剩余的pathname分割为querystring
|
|
if (pathname.length) {
|
|
for(var i = 0,length = Math.ceil(pathname.length)/2; i < length; i++){
|
|
this.http.get[pathname[i * 2]] = pathname[i * 2 + 1] || "";
|
|
}
|
|
}
|
|
this.parseUrl(route);
|
|
return true;
|
|
}
|
|
};
|
|
}); |