Является ли Vue.js несовместимым с обслуживанием запросов POST?

Я пытаюсь сделать [вещь] с проектом Vue.js, созданным с помощью Vue CLI. [Вещь] не является сверхважной для этого вопроса, поэтому для краткости я ее опускаю. Я заметил, когда запускаю локальный веб-сервер для этого проекта с помощью

$ npm run serve

что GET-запросы работают нормально; но POST-запросы дают мне 404 — «Cannot POST». Мне нужно уметь делать и то, и другое.

Используя Express, можно легко обслуживать одну и ту же страницу как с помощью GET, так и с помощью POST, просто добавив router.post(...) в дополнение к router.get(...) по умолчанию. Однако в Vue.js это кажется сложным.

Я провел некоторое время, играя с Vue Router, но внимательно изучив документацию, я не нашел конфигурацию возможность сказать ему «Вот как ответить на запрос POST» — кажется, требуется GET.

Но, может быть, я пытаюсь забить квадратный колышек в круглое отверстие. Vue.js ориентирован на приложения, которые запускаются в браузере, и браузеры отправляют запросы GET (на данный момент меня не интересует отправка форм...), где запросы POST, как правило, больше похожи на веб-приложение/интеграцию/серверную часть своего рода вещь.

Как вы думаете, ребята, есть ли что-то очевидное, что я упускаю, или я должен сделать это «простым» способом и переключиться на Express?

ОБНОВЛЕНИЕ. Моя «проблема» не в Vue.js, а в бинарной службе vue-cli, которая определенно прослушивает GET, но не POST. (GET от Postman завершается успешно, POST от Postman терпит неудачу.) Если я создаю для развертывания, webpack превращает проект в HTML/JS/CSS, который обслуживается другим веб-сервером, а POST работает нормально — просто в режиме разработки, где vue -cli-service обслуживает мое приложение локально, поэтому я не могу использовать POST-запросы.

Есть ли недокументированный способ заставить vue-cli-service отвечать на POST-запросы? Я просмотрел документацию, но ничего не нашел. Я не уверен, как заставить другой веб-сервер обслуживать проект Vue.js, потому что конфигурация веб-пакета... сложна.


person Mike Waldron    schedule 21.06.2019    source источник
comment
Vue — это интерфейсный фреймворк, а не серверный, как экспресс. Маршрутизатор, вероятно, обслуживает только запросы GET, потому что все остальное больше похоже на API.   -  person Flame    schedule 22.06.2019


Ответы (2)


Vue Router не получает запрос (GET) и не отвечает, он просто читает текущий URL-адрес и вставляет соответствующий компонент. Короче говоря, нет, обработчика запросов POST нет... Я бы сказал, что он даже не обрабатывает запросы GET, а просто читает URL-адрес, который выглядит как запрос GET.

Если вы пытаетесь выполнить POST между страницами внутри вашего приложения, Vuex — это то, что вам нужно. Если вы пытаетесь выполнить POST для своего приложения извне, наличие фактического сервера, прослушивающего запросы, которые вы можете пропинговать, будет проще (например, Express).

может быть способ использовать Axios, чтобы сделать это из вашего приложения. Он может прослушивать ответы на запросы POST, поэтому, если бы он прослушивал, я не понимаю, почему он не мог получить. Однако я подозреваю, что вам придется прослушивать порт с компьютера, на котором запущено ваше приложение, что будет серьезной проблемой безопасности (если клиентский браузер/ОС/антивирус даже позволит вам).

person chisnall.io    schedule 24.06.2019
comment
Он получает запрос GET. Я могу проверить это с помощью Postman: GET завершаются успешно; POST не работает. - person Mike Waldron; 03.07.2019
comment
Это просто семантика. Шаблон запрос/ответ — это то, что происходит между клиентами и серверами. Как правило, запрос GET запрашивает определенный ресурс с сервера, который затем предоставляет сервер. То, как работает Vue, отличается от того, что все приложение предоставляется, а затем визуализируется на стороне клиента, а Vuex управляет небольшим окном внутри него. Однако, если вы используете Nuxt, вы можете сделать это на стороне сервера и получить типичный шаблон GET. - person chisnall.io; 04.07.2019

Прошло почти две недели с тех пор, как я опубликовал этот вопрос, но я даже не публиковал вопрос, пока не боролся с проблемой самостоятельно в течение недели. Я, наконец, пришел к решению после долгих головоломок и большего количества тупиков, чем было бы полезно для моего кровяного давления. Вот:

  1. Решив, что лучше всего посмотреть исходный код vue-cli, я случайно заметил включает документацию
  2. Файл README.md в docs/config немного скуден в том, что он говорит об опции devserver, но также упоминает, что поддерживаются все опции для webpack-dev-server. Ох.
  3. В документации Webpack показан параметр devserver.before, который позволяет вам получить доступ к объекту приложения Express и добавить к нему собственное ПО промежуточного слоя
  4. Это позволяет вам перехватывать POST и перенаправлять его как GET.
  5. Что в итоге и сделал этот парень, у которого была точно такая же проблема, как и у меня. (Обратите внимание, что он использовал devserver.setup, который делает то же самое, но устарел в пользу devserver.before.) В vue.config.js включите
devServer: {
    before: function(app) {
        app.post('/about.html', function(req, res) {
          res.redirect('/about.html');
        });
    },
}
person Mike Waldron    schedule 03.07.2019
comment
Отличная идея. Пожалуйста, поправьте меня, если я ошибаюсь, но это будет работать только в среде разработки, где у вас есть веб-пакет, выступающий в качестве вашего сервера? Так что не будет работать в производстве? - person chisnall.io; 04.07.2019
comment
Я считаю, что это правильно. Для моих целей свернутая производственная сборка работала нормально, за исключением того, что между загрузкой новой версии и ее вступлением в силу проходит 5-7 минут. Не страшно для реального развертывания, но невыносимо при разработке. - person Mike Waldron; 06.07.2019
comment
Майк, спасибо за столь активное участие в StackOverflow. Вы решили свою проблему «вслух» и очень помогли мне с похожей дилеммой. - person coltoneakins; 28.01.2020
comment
@coltoneakins Добро пожаловать! Очень рад, что смог кому-то помочь. ???? - person Mike Waldron; 29.01.2020