標籤:regex code ... tty root 執行 res 表達 運行
這關乎於Nodejs的express路由規則(http://hm4123660.iteye.com/blog/2195035)
express 封裝了多種 http 請求方式,我們主要只使用 get和post,可以使用 app.all 擷取所以請求方式,回呼函數有兩個參數分別是 req 和 res,代表請求資訊和響應資訊。
例如:
擷取表達post的參數
var username=req.body.name;//擷取post參數var password=req.body.password;
擷取get參數
訪問URL:http://localhost:3000/test?id=110&password=120
擷取代碼:
app.get(‘/test‘,function(req,res){ res.send("id: "+req.query.id+" password: "+req.query.password);})結果:
一. *通配URL
例如:
app.get(‘/test/*‘,function(req,res){ res.send(req.originalUrl);//req.originalUrl擷取當前URL});
*號可以通配URL為localhost:3000/test/.......的URL
運行結果:
二. /:id的佔位標識符URL
例如:
app.get(‘/test/:userid‘,function(req,res){ res.send("userid: "+req.params.userid);//req.params.userid擷取userid的值});運行結果:
不能繼續使用/
三.next()許可權控制轉移
express的路由控制有個next()功能,在定義了多個路由的時候,使用next對匹配的url會按順序執行,
如果不使用next進行許可權轉移,只會執行第一個滿足的路由規則。
<span class="token comment">next() 函數用於將當前控制權轉交給下一步處理,如果給 next() 傳遞一個參數時,表示出錯資訊</span>
例如:
app.get(‘/test/*‘,function(req,res,next){ //res.send("userid:");//要進行轉移,不要響應用戶端req.temp="給你控制權"; next();//把許可權轉移到下一個路由});app.get(‘/test/next‘,function(req,res){ res.send("content: "+req.temp);})
訪問URL:http://localhost:3000/test/next滿足這兩個路由規則
運行結果:
next()一般用來編寫中介軟體
- 中介軟體一般不直接對用戶端進行響應,而是對請求進行一些預先處理,再傳遞下去;
- 中介軟體一般會在路由處理之前執行;
比如:
// 檢查使用者是否登入中介軟體,所有需要登入許可權的頁面都使用此中介軟體function checkLogin (req, res, next) { if (req.session.user) { next();//檢驗到使用者已登入,轉移許可權閣下一個路由 } else { res.redirect(‘/‘);//否則,頁面重定位,不執行下面路由 }}
滿足了萬用字元*和next()兩個條件(需要傳入),就可以使得二級路由獲得許可權了。
app.get(‘/*‘, function (req, res, next) {// 就是不能有這一句// res.sendFile(__dirname + ‘/../dist/index.html‘);// 上面這一句其實是無關緊要的,並不需要它就可以訪問第一個路由 req.temp="給你控制權"; next();});app.get(‘/test‘,function(req,res){ res.send("content: "+req.temp);})
靜態目錄其實已經在app.use的時候指定了
app.use(‘/‘, express.static(__dirname + ‘/../dist‘));app.use(‘/scripts‘, express.static(__dirname + ‘/../node_modules‘));
res.sendFile之後next或者在擷取了控制權的下一級路由中寫這一句,都會報Forbidden的。
這是單純node中路由的跳轉,在angular2中,不會去載入另一個html檔案,還是要用angular自己的方式實現,參看 Angular2 路由教程 3 - 子模組以及非同步載入(https://gold.xitu.io/entry/58523aa91b69e6006c7e63ac)如果像一般的starter那樣把todo相關的路由定義在一個檔案中,然後在app的路由定義中把所有路由合并到一起。todo.routes.ts的內容如下:
// 省略importexport const TodoRoutes: Route[] = [ { path: ‘todo‘, canActivateChild: [MyTodoGuard], children: [ { path: ‘list‘, component: TodoListComponent, resolve: { todos: MyTodoResolver } }, { path: ‘detail/:id‘, component: TodoDetailComponent, canDeactivate: [ CanLeaveTodoDetailGuard ] } ] }];
然後在app.routes.ts中定義一個路由模組:
const routes: Routes = [ { path: ‘‘, redirectTo: ‘/home‘, pathMatch: ‘full‘ }, { path: ‘home‘, component: HomeComponent }, ...TodoRoutes // 這裡就是將TodoRoutes列表裡的內容合并到routes];@NgModule({ imports: [ RouterModule.forRoot(routes) ], exports: [ RouterModule ]})export class AppRoutingModule { }
最後,在AppModule裡面引入這個路由模組。
這種方式實現的路由無法實現子模組的延時載入,要實現延時載入,首先要將todo模組的路由修改成子路由模組,也就是要修改todo.routes.ts:
// 省略importexport const TodoRoutes: Route[] = [ { path: ‘todo‘, canActivateChild: [MyTodoGuard], children: [ { path: ‘list‘, component: TodoListComponent, resolve: { todos: MyTodoResolver } }, { path: ‘detail/:id‘, component: TodoDetailComponent, canDeactivate: [ CanLeaveTodoDetailGuard ] } ] }];// 通過下面的方式定義了一個子路由模組@NgModule({ imports: [ RouterModule.forChild(TodoRoutes) ], exports: [ RouterModule ]})export class TodoRoutingModule { }
這裡定義了一個子路由模組,TodoRoutingModule,它使用RouterModule.forChild(TodoRoutes)來建立。跟整個App的路由模組比較的話,主路由模組使用RouterModule.forRoot(routes)來定義。
定義好了子路由模組,在子模組裡面引入它既可:
// 省略import@NgModule({ imports: [CommonModule, FormsModule, TodoRoutingModule ], declarations: [TodoListComponent, TodoDetailComponent, TodoItemComponent], providers: [TodoService, MyTodoResolver, MyTodoGuard, CanLeaveTodoDetailGuard]})export class TodoModule {}
這樣就定義好了一個子模組。當使用者開啟/todo/list或/todo/detail/*時,這個子模組裡面的相關頁面就會展示,它也不會跟其他模組有任何互動。也就是說,進入和離開這個子模組,都是通過路由跳轉實現。這個子模組也是完全獨立的,可以獨立開發,也可以很容易就用到其他應用裡面。
angular2地址欄讀取路由