2014-12-30 81 views
10

(如果需要的话,请参阅my last question一些更多的背景资料)如何使BrowserSync与nginx代理服务器一起使用?

我开发使用分离型的前端和后端的应用程序:

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

为了得到两端来相互交谈,同时保持高same-origin policy,我配置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' 

这基本上都有效,但需要注意几个问题,我试图解决:

  • 当我运行一饮而尽任务,根据上面的配置,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代理弄糊涂了。

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

感谢您的任何意见!

回答

5

要更好地控制打开页面的方式,请使用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的,但根据this page,解决第二个问题可能是这个样子:

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"; 
    } 
} 
+0

非常感谢!这很好。我不得不做一些小调整 - (a)在gulpfile中,通过属性'bs.options.urls.local'访问网址而不是'bs.options.url'(看起来像API可能已经稍微改变了(b)在nginx.conf中,将BrowserSync proxy_pass设置为“http:// localhost:3001”而不是“http:// localhost:3002”(我假设这意味着指定BrowserSync服务器,而不是nginx代理)。再次感谢您的时间和帮助 - 他们非常感谢! – Bungle

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"; 
    } 
} 
+2

刚刚发现'proxy_pass http:// localhost:3001 /'不同于'proxy_pass http:// localhost:3001'。通过'proxy_pass http:// localhost:3001',位置部分被自动添加。 – rnons

1

你也可以做到这一点从吞气/ browsersync侧非常简单地使用其proxy option

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

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

+0

确实。这已经足够了! – Dani

0

安装浏览器同步以使用通过websocket在uwsgi上运行的python(django)应用程序。 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; 
    } 

} 
相关问题