Is Vue.js Incompatible With Serving POST Requests?

Viewed 1496

I'm trying to do [thing] with a Vue.js project created with Vue CLI. [Thing] is not super-important to this question, so I'll omit it for the sake of brevity. I've noticed when I run the local web server for this project with

$ npm run serve

that GET requests work just fine; but POST requests give me a 404 - "Cannot POST". I need to be able to do both.

Using Express, it's straightforward to serve the same page with both GET and POST by simply adding router.post(...) in addition to the default router.get(...). However, in Vue.js this seems difficult.

I've spent some time playing with Vue Router, but poring over the documentation I haven't found a configuration option to tell it "Here's how to respond to a POST request" - it seems to require GET.

But maybe I'm trying to pound a square peg into a round hole. Vue.js is geared toward applications that run in the browser, and browsers send GET requests (For the moment I'm not interested in form submissions...) where POST requests tend to be more of a web app/integration/back end kind of a thing.

What do you guys think - is there something obvious I'm missing, or should I do this the "easy" way and switch to Express?

UPDATE: My "problem" is not Vue.js, specifically - it's the binary vue-cli-service, which definitely listens for GETs, but not POSTs. (GETs from Postman succeed; POSTs from Postman fail.) If I build for deployment, webpack turns the project into HTML/JS/CSS, which is served by a different web server and POSTs work just fine - it's just in dev mode where vue-cli-service is serving my application locally that I can't use POST requests.

Is there an undocumented way to make vue-cli-service respond to POST requests? I've scoured the documentation but haven't found anything. I'm not sure how to make another web server serve a Vue.js project, because the webpack configuration is...complex.

2 Answers

Vue Router is not receiving a (GET) request and responding, it is simply reading the current URL and inserting the corresponding component. So in short, no, there is no POST request handler... I'd argue it's not even handling GET requests either, just reading the URL which looks like a GET request.

If you are trying to POST between pages inside your app, Vuex is what you want. If you are trying to POST to your app from outside, having an actual server listening for requests which you can ping will be easier (ie Express).

There may be a way to use Axios to do this from your app. It can listen to responses from POST requests, so if it were listening I don't see why it couldn't receive. However, I suspect you'd have to listen to a port from the machine where your app is running which would be a major security issue (if a client's browser/OS/Antivirus even let you).

It's been nearly two weeks since I posted this question, but I didn't even post the question until I'd been struggling with the problem on my own for a week. I finally came to a solution after much head-desking and more dead ends than it would be healthy for my blood pressure to recount. Here it is:

  1. Deciding perhaps my best bet was to look at the vue-cli source code, I happened to notice it includes documentation
  2. The README.md file under docs/config is a bit sparse-looking in what it says about the devserver option, but it also mentions that All options for webpack-dev-server are supported. Ooh.
  3. The Webpack documentation shows a devserver.before option that allows you to access the Express app object and add your own custom middleware to it
  4. This allows you to intercept the POST and redirect it as a GET
  5. Which this guy, who was having the exact same problem as I was, ultimately did. (Note that he used devserver.setup, which does the same thing, but is deprecated in favor of devserver.before.) In vue.config.js, include
devServer: {
    before: function(app) {
        app.post('/about.html', function(req, res) {
          res.redirect('/about.html');
        });
    },
}
Related