Как заставить 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, но он ожидает только относительный путь.
  • При каждом запуске BrowserSync я получаю (на первый взгляд безобидную) ошибку JavaScript в консоли: 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.

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

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


person Bungle    schedule 30.12.2014    source источник


Ответы (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";
    }
}
person Kalle Björklid    schedule 31.12.2014
comment
Огромное спасибо! Это сработало отлично. Мне пришлось сделать пару мелких правок - (а) в gulpfile доступ к URL-адресу через свойство bs.options.urls.local вместо bs.options.url (похоже, API мог немного измениться?), и (б) в nginx.conf, установка BrowserSync proxy_pass на http://localhost:3001 вместо http://localhost:3002 (я предполагаю, что это означает указать сервер BrowserSync, а не прокси-сервер nginx). Еще раз спасибо за ваше время и помощь - они очень ценятся! - person Bungle; 31.12.2014

Мне это удается только путем добавления /browser-sync/socket.io к URL-адресу proxy_pass.

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";
    }
}
person rnons    schedule 19.05.2015
comment
Только что узнал, что proxy_pass http://localhost:3001/ отличается от proxy_pass http://localhost:3001. С proxy_pass http://localhost:3001 часть местоположения добавляется автоматически. - person rnons; 20.05.2015