項目地址:github.com/Nealyang/Re…javascript
本想等項目作完再連載一波系列博客,隨着開發的進行,也是的確遇到了很多坑,請教了很多人。遂想,何不一邊記錄踩坑,一邊分享收穫呢。分享固然是好的, 若是能作到集思廣益,那豈不是更美。咱們的口號是:堅定不會爛尾前端
本博客爲連載代碼博客同步更新博客,隨着項目日後開發可能會遇到前面寫的不合適的地方會再回頭修改。若有不妥~歡迎兄弟們不嗇賜教。謝謝!java
由於react中使用了react-router,也就是說前端是一個單頁面應用。因此咱們後端幾乎就能夠不去考慮前端路由的配置了。也就是說瀏覽器的url地址請求的頁面咱們是不作任何處理的。 可是假若不作忽略處理的話,固然是不實行的。由於當你刷新的時候,會報404.react
import path from 'path'
import Express from 'express'
import connectHistoryApiFallback from 'connect-history-api-fallback'
const app = new Express();
const port = config.port;
app.use('/',Express.static(path.join(__dirname,"..",'build')));
app.use('/', connectHistoryApiFallback());
複製代碼
connect-history-api-fallback 便可徹底處理完了前端的路由。而後Express.static就是咱們項目中須要託管的靜態資源文件。git
這樣的話,後段部分不須要怎麼關心前端頁面的路由了,而能夠集中精力去處理前端的API請求。因此這裏,我想把前端頁面服務器和處理API請求的服務器分開。也就是說,全部關係到 API請求的部分,我再另起一個服務器,在頁面服務中作一個代理,轉發到另外一個API server 上。 代碼以下:github
import httpProxy from 'http-proxy'
import config from '../config/config'
const app = new Express();
const port = config.port;
app.use('/api',(req,res)=>{
proxy.web(req,res,{target:targetUrl})
});
const targetUrl = `http://${config.apiHost}:${config.apiPort}`;
const proxy = httpProxy.createProxyServer({
target:targetUrl
});
複製代碼
如上代碼,就能夠作到當我訪問/api的時候,HTTPProxy會將個人請求代理到targetUrl上,也就是api服務器。在API server 上咱們作一些關於數據庫的操做以及對前端傳過來數據的操做。web
import Express from 'express'
import config from '../../config/config'
import bodyParser from 'body-parser'
import mongoose from 'mongoose'
import cookieParser from 'cookie-parser'
import session from 'express-session'
const port = config.apiPort;
const app = new Express();
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser('express_react_cookie'));
app.use(session({
secret:'express_react_cookie',
resave: true,
saveUninitialized:true,
cookie: {maxAge: 60 * 1000 * 30}//過時時間
}));
//展現頁面路由
app.use('/', require('./main'));
//管理頁面路由
app.use('/admin', require('./admin'));
mongoose.Promise = require('bluebird');
mongoose.connect(`mongodb://${config.dbHost}:${config.dbPort}/blog`, function (err) {
if (err) {
console.log(err, "數據庫鏈接失敗");
return;
}
console.log('數據庫鏈接成功');
app.listen(port, function (err) {
if (err) {
console.error('err:', err);
} else {
console.info(`===> api server is running at ${config.apiHost}:${config.apiPort}`)
}
});
});
複製代碼
如代碼所示,API server 咱們作了以下幾件事mongodb
關於express-session和cookie-parser這個後面關於免登錄的博客會介紹到。數據庫
express的路由很是的簡單,其實和react思想都是差很少的。就至關於對你請求路徑的一層層篩選過濾。express
好比咱們上面的
//展現頁面路由
app.use('/', require('./main'));
//管理頁面路由
app.use('/admin', require('./admin'));
複製代碼
那麼如今讓咱們看看admin 和 main 中到底寫了些什麼
admin.js
import Express from 'express'
const router = Express.Router();
import User from '../../models/user'
import {responseClient,md5,MD5_SUFFIX} from '../util'
router.get('/getUsers',(req,res)=>{
let skip =(req.query.pageNum-1)<0?0:(req.query.pageNum-1)*10;
let responseData = {
total:0,
list:[]
};
User.count()
.then(count=>{
responseData.total = count;
User.find(null,'_id username type password',{skip:skip,limit:10})
.then((result)=>{
responseData.list = result;
responseClient(res,200,0,'',responseData)
})
.catch(err=>{
responseClient(res);
})
});
});
module.exports = router;
複製代碼
如上代碼,咱們使用express.Router來產生一個router對象,別迷糊,咱們徹底能夠理解爲這個router就是一個express的實例。跟前面的/a啓動app server沒有任何兩樣。一樣的監聽一個請求參數,而後回調函數。
注意這個router.get('/getUsers')真正匹配的完整請求路徑是:/api/admin/getUsers
上面代碼中的對數據庫的操做咱們能夠暫時不要理會。後續會介紹。這裏重點關注在後端路由的配置上。
關於後端的路由,也就是/api/xxx請求後面的xxx咱們該如何設計,這個因人而異。本身怎麼舒服怎麼來。固然,工做中得遵照一些團隊約束是固然,這個demo,我就隨意來了。
而後該demo的後端服務起的兩個服務。一個是前端頁面服務。一個是API服務。全部的請求統一到頁面 server 中。約束api請求的寫法。當爲/api請求發來時,咱們則經過HTTPProxy來代理到API server上。
數據庫的鏈接、/api 請求後的後端路由控制,都是在api server上完成的。
歡迎關注我的微信公衆號: Nealyang 全棧前端,獲取第一手文章推送和免費全棧電子書分享福利