BrowserSync如何使用nginx代理服务器?

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

我正在开发一个应用程序,使用一个解耦的前端和后端:

  • 后端是一个Rails应用程序(在localhost:3000上提供),主要提供一个REST API。
  • 前端是一个AngularJS应用程序,我正在使用Gulp构build本地服务(使用BrowserSync )在localhost:3001

为了使两端互相交stream,在遵守同源策略的同时 ,我configuration了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服务器。

来自我的gulpfile.coffee的BrowserSync任务:

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

这一切基本上工作,但有一些警告,我试图解决:

  • 当我运行gulp任务时,根据上面的configuration,BrowserSync在http://localhost:3001/index.html#/foo加载一个Chrome选项卡。 因为我使用nginx代理,但是,我需要的端口是3002.有没有办法告诉BrowserSync,“在端口3001上运行,但在端口3002上启动”? 我尝试使用startPath的绝对path,但它只需要一个相对path。
  • 每次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 。 不知道这意味着什么,但我的假设是,浏览器同步在某种程度上被nginx代理弄糊涂了。

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

感谢您的任何意见!

要更好地控制如何打开页面,请使用opn而不是浏览器同步的机制。 就像这样(在JS中 – 对不起,我的咖啡脚本有点生疏):

 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配置进行条件化/改变。

设置浏览器同步,以通过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; } }