Express应用访问根路径出现Cannot GET/错误求助(附代码)
嘿,我仔细看了你的问题和代码,马上就发现了几个导致这个错误的关键原因,咱们一步步来解决:
直接原因:server.js里根本没配根路径的GET路由
你运行node server的时候,加载的是server.js的代码,但这个文件里只写了POST /session、GET /user、POST /user这几个路由,完全没有处理GET /请求的逻辑——这就是访问根路径时返回Cannot GET /的最直接原因。
如果想让根路径有响应,你可以直接在server.js里加一段根路由:
app.get('/', function(req, res) { res.send('服务器正常运行哦!'); // 也可以返回你需要的JSON数据或者页面,比如res.json({msg: '欢迎访问我的应用'}) });
更重要的问题:两个文件的Express实例冲突了
你同时有server.js和app.js两个文件,它们各自创建了独立的Express应用,还都监听了3000端口!这不仅会导致端口占用冲突,更关键的是——你运行node server时,只会执行server.js的代码,完全不会加载app.js里的任何路由配置,这就是你觉得“路由都配好了但没用”的核心原因!
解决冲突的两种方案,选一个就行:
方案一:用app.js作为入口文件
如果你本来就想使用app.js里的那些路由(比如/api/users、/指向的static控制器),那你应该运行node app.js而不是node server.js。只要./app/controllers/static这个文件里正确处理了GET /请求,根路径就能正常访问了。
方案二:整合两个文件的代码
要是你想保留server.js作为入口,就得把app.js的路由逻辑整合进来。步骤如下:
- 先修改
app.js,删除最后监听端口的代码,把Express实例导出:
"use-strict" var express = require('express'); var router = express.Router(); var morgan = require('morgan'); var bodyParser = require('body-parser'); var app = express(); /*app.use(morgan('dev'));*/ app.use('/public/app/controllers/routes', router); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use(require('./config/auth')) app.use('/api/users', require('./app/controllers/api/users')) app.use('/api/sessions', require('./app/controllers/api/sessions')) app.use('/api/products', require('./app/controllers/api/products')) app.use('/api/companies', require('./app/controllers/api/companies')) app.use('/api/stockists', require('./app/controllers/api/stockists')) app.use('/api/employees', require('./app/controllers/api/employees')) app.use('/api/sales', require('./app/controllers/api/sales')) app.use('/', require('./app/controllers/static')) // 删掉原来的server.listen代码,换成导出app module.exports = app;
- 然后修改
server.js,引入app.js的实例,把两个文件的路由合并:
var express = require('express'); var bodyParser = require('body-parser'); var User = require('./app/models/user'); var jwt = require('jwt-simple') var _ = require('lodash') var bcrypt = require('bcrypt') var app = express(); // 保留server.js原有的中间件和路由 app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); var secretkey = "supersecretkey" app.post('/session', function(req, res, next) { // 你的原代码不变 console.log(req.body.username); User.findOne({ username: req.body.username }).select('password').exec(function(err, user) { if (err) { return next(err) } if (!user) { return res.send(401) } bcrypt.compare(req.body.password, user.password, function(err, valid) { if (err) { return next(err) } if (!valid) { return res.send(401) } var token = jwt.encode({ username: req.body.username}, secretkey) res.json(token) }) }) }) app.get('/user', function(req, res, next) { // 你的原代码不变 var token = req.headers['x-auth'] console.log(token) var auth = jwt.decode(token, secretkey) User.findOne({ username: auth.username }, function(err, user) { res.json(user) }) }) app.post('/user', function(req, res) { // 你的原代码不变 var user = new User({ username: req.body.username }) bcrypt.hash(req.body.password, 10, function(err, hash) { user.password = hash user.save(function(err, user) { if (err) { throw next(err) } res.json(user); }) }) }) // 引入app.js里的路由和中间件 var appRoutes = require('./app'); app.use(appRoutes); // 统一在这里监听端口 app.listen(3000, () => { console.log('服务器在3000端口运行啦!'); });
最后检查一下:static控制器是否正确处理根路由
如果你选了方案一,运行node app.js,那一定要确认./app/controllers/static这个文件里有没有配置GET /的路由。比如这个文件应该长这样:
var express = require('express'); var router = express.Router(); // 处理根路径的GET请求 router.get('/', function(req, res) { res.send('欢迎来到首页!'); // 要是你想返回静态页面,可以用res.sendFile,比如: // const path = require('path'); // res.sendFile(path.join(__dirname, '../../views/index.html')); }); module.exports = router;
这样调整之后,你再访问根路径就不会出现Cannot GET /的错误啦!
内容的提问来源于stack exchange,提问作者lokesh karanam

