Как заставить BrowserSync работать с прокси-сервером nginx?

(При необходимости см. Мой последний вопрос для получения дополнительной информации.)

Я занимаюсь разработкой приложения, которое использует разделенный фронт и бэкэнд:

  • Бэкэнд представляет собой приложение Rails (обслуживается на localhost:3000) который в первую очередь предоставляет REST API.
  • Интерфейс - это приложение AngularJS, которое я создаю вместе с Gulp и которое обслуживаю локально (используя BrowserSync) в localhost:3001,

Чтобы заставить два конца общаться друг с другом, соблюдая при этом политику одного и того же происхождения, я настроил nginx в качестве прокси между ними, доступным на localhost:3002, Вот мой nginx.conf:

worker_processes 1;

events {
  worker_connections 1024;
}

http {
  include mime.types;
  default_type application/octet-stream;
  sendfile on;
  keepalive_timeout 65;

  server {
    listen 3002;
    root /;

    # Rails
    location ~ \.(json)$ {
      proxy_pass http://localhost:3000;
    }

    # AngularJS
    location / {
      proxy_pass http://localhost:3001;
    }
  }
}

В основном любые запросы на .json файлы, которые я отправляю на сервер Rails, и любые другие запросы (например, для статических ресурсов), которые я отправляю на сервер BrowserSync.

Задача BrowserSync из моего gulpfile.coffee:

gulp.task 'browser-sync', ->
  browserSync
    server:
      baseDir: './dist'
      directory: true
    port: 3001
    browser: 'google chrome'
    startPath: './index.html#/foo'

Все это в основном работает, но с несколькими оговорками, которые я пытаюсь решить:

  • Когда я запускаю задачу gulp, основываясь на приведенной выше конфигурации, BrowserSync загружает вкладку Chrome по адресу http://localhost:3001/index.html#/foo, Так как я использую прокси-сервер nginx, мне нужно, чтобы порт был 3002. Есть ли способ сказать BrowserSync, "запустить на порту 3001, но запустить на порту 3002"? Я пытался использовать абсолютный путь для startPath, но он ожидает только относительный путь.
  • Я получаю (казалось бы, мягкую) ошибку JavaScript в консоли каждый раз, когда запускается BrowserSync: WebSocket connection to 'ws://localhost:3002/browser-sync/socket.io/?EIO=3&transport=websocket&sid=m-JFr6algNjpVre3AACY' failed: Error during WebSocket handshake: Unexpected response code: 400, Не уверен, что именно это означает, но я предполагаю, что BrowserSync каким-то образом смущен прокси-сервером nginx.

Как я могу исправить эти проблемы, чтобы это работало без проблем?

Спасибо за любой вклад!

4 ответа

Решение

Чтобы лучше контролировать процесс открытия страницы, используйте opn вместо механизма синхронизации браузера. Примерно так (в JS - извините, мой Coffee Script немного ржавый):

browserSync({
    server: {
        // ...
    },
    open: false,
    port: 3001
}, function (err, bs) {
    // bs.options.url contains the original url, so
    // replace the port with the correct one:
    var url = bs.options.urls.local.replace(':3001', ':3002');
    require('opn')(url);
    console.log('Started browserSync on ' + url);
});

Я незнаком с Nginx, но, согласно этой странице, решение второй проблемы может выглядеть примерно так:

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    # ...

    # BrowserSync websocket
    location /browser-sync/socket.io/ {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}

Я преуспеваю только добавляя /browser-sync/socket.io на proxy_pass url.

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    # ...

    # BrowserSync websocket
    location /browser-sync/socket.io/ {
        proxy_pass http://localhost:3001/browser-sync/socket.io/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}

Вы также можете сделать это со стороны gulp/browsersync очень просто, используя опцию прокси:

gulp.task('browser-sync', function() {
    browserSync({
        ...
        proxy: 'localhost:3002'
    });
});

Это означает, что ваш браузер подключается к браузерной синхронизации напрямую, как обычно, через gulp, за исключением того, что теперь он прокси-сервер nginx. До тех пор, пока ваш интерфейс не будет жестко кодировать хосты / порты в URL-адресах, запросы к Rails будут проходить через прокси-сервер и иметь одинаковое происхождение, так что вы все равно сможете POST и тому подобное. Это может быть желательно для некоторых, так как это изменение для параметра разработки идет в разделе разработки вашего кода (gulp+browsersync) по сравнению с условным изменением / изменением вашей конфигурации nginx, которая также работает в рабочей среде.

Настройка синхронизации браузера для работы с приложением python (django), которое работает на uwsgi через websocket. Приложение Django имеет префикс /app для генерации URL, который выглядит как http://example.com/app/admin/

server {
  listen 80;
  server_name example.com;

  charset utf-8;

  root /var/www/example/htdocs/static;
  index index.html index.htm;

  try_files $uri $uri/ /index.html?$args;

  location /app {
    ## uWSGI setup
    include     /etc/nginx/uwsgi_params;
    uwsgi_pass  unix:///var/run/example/uwsgi.sock;
    uwsgi_param SCRIPT_NAME /app;
    uwsgi_modifier1 30;
  }

  location /media  {
    alias /var/www/example/htdocs/storage;
  }

  location /static {
    alias /var/www/example/htdocs/static;
  }

}
Другие вопросы по тегам