14

(如果需要,请参阅我的最后一个问题以获取更多背景信息。)

我正在开发一个使用分离的前端和后端的应用程序:

  • 后端是一个localhost:3000主要提供 REST API 的 Rails 应用程序(在 上提供服务)。
  • 前端是一个AngularJS应用程序,我正在使用 Gulp 构建它并在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 在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 代理弄糊涂了。

如何解决这些问题以使其无缝运行?

感谢您的任何意见!

4

4 回答 4

8

要更好地控制页面的打开方式,请使用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";
    }
}
于 2014-12-31T15:13:26.717 回答
3

我只有通过附加/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";
    }
}
于 2015-05-19T16:01:44.933 回答
2

您也可以通过使用其代理选项从 gulp/browsersync 方面非常简单地执行此操作:

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

这意味着您的浏览器像往常一样通过 gulp 直接连接到 browsersync,除了现在它代理 nginx。只要您的前端没有在 URL 中硬编码主机/端口,对 Rails 的请求将通过代理并具有相同的来源,因此您仍然可以 POST 等。这对于某些人来说可能是可取的,因为对开发设置的这种更改是在代码的开发部分(gulp+browsersync)而不是条件化/更改也在生产中运行的 nginx 配置。

于 2016-04-22T00:16:52.827 回答
0

设置浏览器同步以使用通过 websocket 在 uwsgi 上运行的 python (django) 应用程序。Django 应用程序以 /app 为前缀,以生成类似于http://example.com/app/admin/的 url

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;
  }

}
于 2016-07-14T13:39:17.883 回答