-1

请帮助解决路由问题:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var router = express.Router();

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(methodOverride());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// data storage in memory
var widgets = [
  {id: 1,
   name: 'My special widget',
   price: 100.00,
   descr: 'A widget beyond price'},
];

// routes

app.use(router);

router.get('/', function(req, res, next) {
  res.render('index');
});

router.get('/widgets', function(req, res) {
  res.send(widgets);
});

router.post('/widgets/add', function(req, res) {
  var indx = widgets.length + 1;
  widgets[widgets.length] = {  id: indx,
                               name: req.body.widgetname,
                               price: parseFloat(req.body.widgetprice),
                               descr: req.body.widgetdesc
                            };
  console.log('added ' + widgets[indx - 1]);
  res.send('Widget ' + req.body.widgetname + ' added with id ' + indx);  
});

router.get('/widgets/:id', function(req, res) {
  var indx = parseInt(req.params.id) - 1;
  if (!widgets[indx]) {
    res.send('There is no widget with id of ' + req.params.id);
  } else {
    res.send(widgets[indx]);
  }
});

router.put('/widgets/:id/update', function(req, res) {
  var indx = req.params.id - 1;
  widgets[indx] = {id: indx,
                   name: req.body.widgetname,
                   price: parseFloat(req.body.widgetprice),
                   descr: req.body.widgetdesc};
  console.log(widgets[indx]);
  res.send('updated ' + req.params.id);
});

router.delete('/widgets/:id/delete', function(req, res) {
  var indx = req.params.id - 1;
  delete widgets[indx];
  console.log('deleted ' + req.params.id);
  res.send('deleted ' + req.params.id);  
});

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
  app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
      message: err.message,
      error: err
    });
  });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
  res.status(err.status || 500);
  res.render('error', {
    message: err.message,
    error: {}
  });
});


module.exports = app;

我在 VIEWS 文件夹中有 3 个 html 文件:1 - 索引

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8" />
	<title>Widgets</title>
</head>
<body>

	<form action="/widgets/add" method="POST" enctype="application/x-www-form-urlencoded">
		
		<p>Widget name:<input type="text" name="widgetname" id="widgetname" size="25" required /></p>

		<p>Widget price:<input type="text" name="widgetprice" id="widgetprice" size="25" required
			pattern="^\$?([0-9]{1,3},([0-9]{3},)*[0-9]{3}|[0-9]+)(.[0-9][0-9])?$" /></p>

		<p>Widget description: <br/> <textarea name="widgetdesc" id="widgetdesc" cols="20"
			rows="5">Describe widget</textarea></p>
		<p>
			<input type="submit" name="submit" id="submit" value="Submit" />
			<input type="reset" name="reset" id="reset" value="Reset" />
		</p>

	</form>

</body>
</html>

2 - 更新

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8" />
	<title>Widgets</title>
</head>
<body>

	<form method="POST" action="/widgets/1/update" enctype="application/x-www-form-urlencoded">
		
		<p>Widget name:<input type="text" name="widgetname" id="widgetname" size="25" value="Me special widget" required /></p>

		<p>Widget price:<input type="text" name="widgetprice" id="widgetprice" size="25" required
			pattern="^\$?([0-9]{1,3},([0-9]{3},)*[0-9]{3}|[0-9]+)(.[0-9][0-9])?$" value="100.00" /></p>

		<p>Widget description: <br/> <textarea name="widgetdesc" id="widgetdesc" cols="20"
			rows="5">A widget beyond price</textarea></p>

		<input type="hidden" value="put" name="_method" />

		<p>
			<input type="submit" name="submit" id="submit" value="Submit" />
			<input type="reset" name="reset" id="reset" value="Reset" />
		</p>

	</form>

</body>
</html>

3 - 删除

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8" />
	<title>Widgets</title>
</head>
<body>
	<p>Are you sure you want to delete widget?</p>
	
	<form method="POST" action="/widgets/1/delete" enctype="application/x-www-form-urlencoded">
		
		<input type="hidden" value="delete" name="_method" />
		
		<p>
			<input type="submit" name="submit" id="submit" value="Delete Widget" />
		</p>

	</form>

</body>
</html>

问题是 PUT 和 DELETE 显示错误,我无法理解我应该怎么做才能纠正它。

4

1 回答 1

1

这个例子有一些问题。我会从最重要到最不重要来解决它们。

方法混乱

RESTRE表示状态传输定义了具有不同目的的 HTTP 动词。

  • GET:获取资源
  • POST:创建资源
  • PUT:覆盖资源
  • PATCH:部分修改资源
  • DELETE:删除资源
  • 还有一些其他的

需要注意的一点是,在快速路由器中,即使 URL 相同,POST URL 处理程序也不会匹配 GET 请求。即使 URL 相同,操作也不同。

因此,当您尝试 POST 时看到 404 错误的原因/widgets/1/update是因为您没有定义 POST 处理程序,而是定义了 PUT 处理程序

不正确的 REST URL

因为您可以对同一个 URL 进行多个操作,所以出现了一种标准。由于 URL 旨在引用资源,而不是操作,因此请尝试将操作词保留在 URL 之外。

例如。无需为 . 设置 PUT 处理程序/widgets/1/update,只需为 . 执行 PUT 处理程序即可/widgets/1。您正在更新的事实已经很明显,因为您正在执行 PUT 请求。

以同样的方式,为/widgets/1而不是创建一个 DELETE 处理程序/widgets/1/delete

请记住,这不会与 GET 或 DELETE 处理程序发生冲突,/widgets/1因为动词不同。

POST 有点不同。而不是 POST /widgets/add,使用 POST /widgets

想象一下,如果你要表达你想做的事情:

在小部件中创建记录

或者

发布/widgets

“添加”或“创建”已经很明显了,因为它是一个 POST 请求。

代码顺序

这是一个小小的抱怨。.use()在实际定义路由之前,您正在使用路由器。这是因为javascript处理对象变量的方式,但它向后看。

了解快递

app在您的代码中可以处理.post(),.get()等。没有理由在您的代码中构造和使用路由器。

express.Router()当您想在部分 URL 上安装一大堆路径或保持一组 URL 精神分离时使用例如:

var app = express()
var apiRoutes = require("./api-router")
var frontendRoutes = require("./frontend-router")

app.use("/api", apiRoutes)
app.use(frontendRoutes)
于 2015-10-08T12:45:42.770 回答