Reputation: 2153
Ok So I have a simple node.js / express.js / mongodb app set up here with my config as follows.
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");
The problem lies when I try to make PUT or DELETE requests. My form is this simple
<form method="POST" action="/users/#{user.name}">
<input type="hidden" name="_method" value="PUT"/>
</form>
Now my router catches the route with the express .put() method
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);
});
})
When I make the request I simply get a "Cannot PUT" or "Cannot DELETE" error.
I have tried to make this same request via chomes RESTful client with the same result.
I have read a topic witch has the same problem as me although following the comments the answers did not solve my problem.
Questions I have looked into expressjs support for method delete and put without the methodoverride
Are the PUT, DELETE, HEAD, etc methods available in most web browsers?
Along with a few others. I have also referenced the express.js and mongo documentation several times. I just cant think what could be going wrong.
Any help is appreciated.
Upvotes: 21
Views: 61784
Reputation: 11
one solution is to use cors middleware for you PUT,PATCH and DELETE requests like this in your app.js file like this:
first install the cors package via npm :
npm i cors
then add the following code to your app.js:
const cors = require('cors')
app.use(cors())
Upvotes: 1
Reputation: 8243
Change res.redirect('path')
to res.redirect(303, 'path')
In Put
and Delete
, if you want to redirect to get
address, you should pass 303 as first parameter. (source)
Upvotes: 0
Reputation: 91
app.post("/movies/:id") is one solution. If you still want to use app.put("/movies/:id") then try this:
make sure your form has the following attributes:
action="/movies/<%= movies._id %>?_method=PUT " method="POST" >
These two solutions worked for me. If you are following REST, then use the method-ovveride else app.post() will also do the trick
Upvotes: 0
Reputation: 99
If your using method override, make sure you have declared it before you use your routes. That was the problem I was having.
Upvotes: 1
Reputation: 3691
Unless there is strange magic at work, your form makes a POST request, not a PUT. If you want to PUT, I would suggest using the jQuery.ajax
function with a type: 'PUT'
parameter, like this answer, from a form handler, see jQuery.submit
. Don't forget to return false
so that the form doesn't submit twice.
Upvotes: 1
Reputation: 47993
Update
As Jonathan Lonowski pointed out PUT
can also be used, so you can ignore my old answer.
Getting Cannot PUT
or Cannot POST
errors, means your callback is not executing successfully. My guess is that Users.update
is failing, which is why it cannot POST or PUT. Can you check it.
Old answer
Try changing this line
app.put('/users/:name', function(req, res) {
to
app.post('/users/:name', function(req, res) {
since you are trying to submit the form
Upvotes: 14
Reputation: 123453
Is the <form>
you listed in a view or a static
file under __dirname + "/public"
?
Within a static file, the #{user.name}
probably isn't being replaced with the user
's name
and will be treated as a URL Fragment.
The <form>
will actually submit to /users/
rather than /users/:name
since that's the path
:
console.log(url.parse('/users/#{user.name}'));
{ hash: '#{user.name}',
pathname: '/users/',
path: '/users/',
href: '/users/#{user.name}' }
The <form>
should be generated from a view if it isn't since the action
needs to be dynamic and data-driven. With Jade and assuming user
is a member of locals
, that would be:
form(method='POST', action='/users/' + user.name)
input(type='hidden', name='_method', value='PUT')
Upvotes: 3