先上react App代碼html
class App extends React.Component { render() { return ( <BrowserRouter> <div> <Link to="/lottery">to lottery</Link> <Route path="/lottery" component={Lottery} exact /> <Route path="/a" render={() => <div>in a</div>} exact /> </div> </BrowserRouter> ) } }
點擊後能夠正常跳轉至lottery路由,忽略醜陋的界面...前端
這時刷新就404找不到頁面了react
react的BrowserRouter用的是Html5提供的HistoryApi方法,Link組件其實是調用了History.pushState(),而後經過監聽history狀態去展現或者隱藏組件。因此當刷新時,也就是向服務器發送了這個路徑的請求,而服務器上實際是沒有對這個路徑的請求作任何處理的,故返回的是404。服務器
app.use(views(path.resolve(__dirname, '../www/dist'), {extension: 'html'})) app.use(async (ctx, next) => { console.log(ctx.path) await next() }) app.use(router.routes()) router.all(/\.js/i, static(path.resolve(__dirname, '../www/dist'))) router.all('*', async ctx => { await ctx.render('index') })
這裏須要注意的是koa-views提供的render方法是異步的,因此要用await,不然也是返回404,至關於對路由沒有進行任何處理。app
只要不是以.js結束的路由請求都返回index.html,js類型的就從項目打包出來的靜態資源裏找,至關於把路由的控制權交給了前端。
前端react App只須要對匹配不到的路由作下處理就ok了。koa
<BrowserRouter> <div> <Switch> <Route path="/lottery" component={Lottery} exact /> <Route path="/a" render={() => <div>in a</div>} exact /> <Route render={() => <div>404頁面</div>}></Route> </Switch> </div> </BrowserRouter>