Экспресс не может использовать метод PUT/DELETE. Что происходит не так?
Итак, у меня есть простое приложение node.js/express.js/mongodb, настроенное здесь с моей конфигурацией следующим образом.
var express = require('express'),
mongoose = require('mongoose');
http = require('http');
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
//middleware stack
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + "/public"));
});
mongoose.connect("mongodb://localhost/hello");
Проблема заключается в том, что я пытаюсь сделать запросы PUT или DELETE. Моя форма проста:
<form method="POST" action="/users/#{user.name}">
<input type="hidden" name="_method" value="PUT"/>
</form>
Теперь мой маршрутизатор ловит маршрут с помощью метода экспресс .put()
app.put('/users/:name', function(req, res) {
var b = req.body;
Users.update(
{ name: req.user.name },
{ name: b.name, age: b.age, email: b.email },
function(err) {
res.redirect('/users/'+b.name);
});
})
Когда я делаю запрос, я просто получаю сообщение "Can not PUT" или "Can not DELETE".
Я попытался сделать этот же запрос через chomes RESTful-клиент с тем же результатом.
Я прочитал тему, которая имеет ту же проблему, что и я, хотя, следуя комментариям, ответы не помогли решить мою проблему.
Вопросы, которые я изучил
expressjs поддержка метода delete и put без методаoveroverride
Доступны ли методы PUT, DELETE, HEAD и т.д. в большинстве веб-браузеров?
Наряду с несколькими другими.
Я также неоднократно ссылался на документацию express.js и mongo.
Я просто не могу подумать, что может пойти не так.
Любая помощь приветствуется.
Ответы
Ответ 1
Обновление
Как отметил Джонатан Лоновски PUT
, вы можете игнорировать мой старый ответ.
Получение ошибок Cannot PUT
или Cannot POST
означает, что ваш обратный вызов не выполняется успешно. Я предполагаю, что Users.update
не работает, поэтому он не может POST или PUT. Вы можете проверить это.
Старый ответ
Попробуйте изменить эту строку
app.put('/users/:name', function(req, res) {
to
app.post('/users/:name', function(req, res) {
так как вы пытаетесь отправить форму
Ответ 2
Отображается ли <form>
в представлении или в файле static
под __dirname + "/public"
?
В статическом файле #{user.name}
, вероятно, не заменяется user
name
и будет рассматриваться как URL Fragment.
<form>
будет фактически подчиняться /users/
, а не /users/:name
, так как path
:
console.log(url.parse('/users/#{user.name}'));
{ hash: '#{user.name}',
pathname: '/users/',
path: '/users/',
href: '/users/#{user.name}' }
<form>
должен быть сгенерирован из представления, если это не так, поскольку action
должен быть динамическим и управляемым данными. С Jade и предполагая, что user
является членом locals
, это будет:
form(method='POST', action='/users/' + user.name)
input(type='hidden', name='_method', value='PUT')
Ответ 3
Если на работе нет странной магии, ваша форма делает запрос POST, а не PUT. Если вы хотите PUT, я бы предложил использовать jQuery.ajax
с параметром type: 'PUT'
, например этот ответ, от обработчика формы, см. jQuery.submit
. Не забывайте return false
, чтобы форма не отправлялась дважды.
Ответ 4
Если вы используете переопределение метода, убедитесь, что вы объявили его, прежде чем использовать ваши маршруты. Это была моя проблема.
Ответ 5
app.post("/movies/: id") является одним из решений. Если вы все еще хотите использовать app.put("/movies/: id"), попробуйте следующее:
- Установите метод ovveride из npm.
- Требуйте это в вашем файле app.js.
- Откройте форму, откуда вы хотите вызвать запрос PUT
-
убедитесь, что ваша форма имеет следующие атрибуты:
action = "/movies/<% = movies._id%>? _ method = PUT" method = "POST">
Эти два решения помогли мне. Если вы следуете за REST, то используйте метод-ovveride, иначе app.post() также добьется цели
Ответ 6
Измените res.redirect('path')
на res.redirect(303, 'path')
В Put
и Delete
, если вы хотите перенаправить на адрес get
, вы должны передать 303 в качестве первого параметра. (source)