Проблема:
Вы используете Webpack для обслуживания своего кода в режиме dev-localhost, но хотите, чтобы вызовы API-интерфейсов SPA направлялись на прокси-сервер.

Пример:
Ваш webpack-dev-сервер обслуживает код по адресу http: // localhost: 9000 /, но ваш серверный api работает по адресу http: // localhost: 3000 / api /. Когда ваш SPA загружается, он пытается получить код из http: // localhost: 9000 / api / - как мы можем это исправить?

Запустите webpack-dev-server
Сначала настройте Webpack-dev-server. Из моей серии Использование Webpack с устаревшим Angular у нас есть репозиторий github, который уже настроен для серверного кода веб-пакета.

./node_modules/.bin/webpack-dev-server --config webpack.config.js --watch

SPA обслуживается из порта 9000

Project is running at http://localhost:9000/
webpack output is served from /
Content not from webpack is served from /Users/thinkjones/dev/GeneConroyJonesArticles/webpack_plunge/dist

Добавить воображаемый сервер API

Итак, давайте добавим api, работающий на другом порту. Самый быстрый способ серверить json на конечной точке api - использовать отличный json-server. Первая установка:

npm install --save-dev  json-server

Затем создайте файл db.json:

{
  "posts": [
    { "id": 1, "title": "json-server", "author": "typicode" }
  ],
  "comments": [
    { "id": 1, "body": "some comment", "postId": 1 }
  ],
  "profile": { "name": "typicode" }
}

Теперь мы можем запустить сервер так:

./node_modules/.bin/json-server --watch сервер / db.json

\{^_^}/ hi!
Loading server/db.json
Done
Resources
http://localhost:3000/posts
http://localhost:3000/comments
http://localhost:3000/profile
Home
http://localhost:3000
Type s + enter at any time to create a snapshot of the database
Watching...

Но мы хотим обслуживать конечные точки из / api / blah, поэтому давайте использовать Node для настройки сервера. Добавить server / server.js

// server.js
var jsonServer = require('json-server')
var server = jsonServer.create()
var router = jsonServer.router('server/db.json')
var middlewares = jsonServer.defaults()

server.use(middlewares)
server.use('/api', router)  // Rewrite routes to appear after /api
server.listen(3000, function () {
    console.log('JSON Server is running')
})

Теперь запустите сервер с узлом:

node server/server.js

Как это просто и круто!

Два сервера

Подводя итог, у нас есть код, обслуживаемый с: http: // localhost: 9000 / и api по адресу http: // localhost: 3000 / api / posts.

Затем давайте изменим наше приложение Angular для запроса данных из API.

Запросить GET из API.

На нашей целевой странице мы попытаемся получить сообщения из API-интерфейса, который дает нам:

myApp.controller('LandingCtrl', function($http){
    var app = this;
    app.greeting = 'Welcome to the Landing Page';
    $http.get('api/posts').then(function(response){
        app.posts = response;
    });
});

А затем шаблон для отображения сообщений:

<div>
    <h1>Landing Page</h1>
    {{ctrl.greeting}}
    <a ui-sref="about"><< To the about page</a>

    <div ng-repeat="post in ctrl.posts">
        {{post.id}}:{{post.title}} by {{post.author}}
    </div>
</div>

Но когда мы запускаем этот код, мы получаем:

Как и ожидалось, это не удается, потому что наш api работает на порту 3000, а не на 9000, и поскольку мы использовали относительные URL-адреса в запросе Angular $ http, по умолчанию он указывает на то, откуда код обслуживается.

Решение 1. Давайте просто перепишем URL-адреса в клиентском коде.

Errr Нет, не надо! Но для иллюстрации:

myApp.controller('LandingCtrl', function($http){
    var app = this;
    app.greeting = 'Welcome to the Landing Page';
    $http.get('http://localhost:3000/api/posts').then(function(response){
        app.posts = response.data;
    });
});

Множество причин, по которым мне лично это не нравится, и все они связаны с необходимостью динамически управлять основой запроса с помощью комбинаций http (s), сервера и порта. Кроме того, теперь мы засоряем наш код информацией о том, где установлено приложение, что затрудняет управление развертыванием тестовых кластеров и запуском на разных серверах.

Так есть ли другой способ?

Решение 2. Используйте http-proxy-middleware для прокси-запросов к API.

Сервер разработки Webpack использует« http-proxy-middleware , чтобы опционально проксировать запросы к отдельному, возможно внешнему, внутреннему серверу. Ниже приведен образец конфигурации ».

Ссылка на документацию

Добавьте свойство прокси в конфигурацию devServer в webpack.config.js:

devServer: {
    contentBase: path.join(__dirname, "dist"),
    compress: true,
    port: 9000,
    proxy: {
        '/api': {
            target: 'http://localhost:3000',
            secure: false
        }
    }
}

Перезагрузите сервер webpack dev, и когда вы посетите сервер кода по адресу http: // localhost: 9000 / api / posts, вы увидите те же результаты, что и http: // localhost: 3000 / api / posts с сервера api. Ура!! И мы не засоряли наш код грязным кодом модификации основы URL.

Заключение

Это решение полезно для разработчиков, у которых есть код и конечные точки RESTful, обслуживаемые из двух разных мест. Это часто происходит, особенно когда вы используете инструменты JS для создания клиента, но, возможно, используете комбинации стилей Python-Flask, Java-Tomcat для обслуживания конечных точек RESTful. Это решение относительно простое и не требует изменения кода для управления различными средами развертывания.

Весь код на гитхабе здесь