【问题标题】:Gulp browser-sync - redirect API request via proxyGulp browser-sync - 通过代理重定向 API 请求
【发布时间】:2014-08-20 16:50:43
【问题描述】:

我正在尝试使用 gulp 和浏览器同步重定向我的 API 请求:

gulp.task('browser-sync', function () {

   var files = [
      '../index.html',
      '../views/**/*.html',
      '../assets/css/**/*.css',
      '../assets/js/**/*.js'
   ];

   var url = require('url'),
   proxy = require('proxy-middleware');
   var proxyOptions = url.parse('http://localhost:8000/api');
   proxyOptions.route = '/api';

   browserSync.init(files, {
      server: {
         baseDir: '..',
         middleware: [proxy(proxyOptions)]
      }
   });

});

但是当调用被发送到 API 时,我得到了这个响应:

Error: connect ECONNREFUSED
    at errnoException (net.js:904:11)
    at Object.afterConnect [as oncomplete] (net.js:895:19)

知道我做错了什么吗?

【问题讨论】:

    标签: api proxy gulp middleware browser-sync


    【解决方案1】:

    查看official documentation about using BrowserSync with Gulp。我能够在 /api 上使用代理启动 BrowserSync 并运行,没有任何问题。

    检查以确保没有其他东西在使用端口 8000。您可以通过 port option when initializing BrowserSync 更改 BrowserSync 使用的端口。

    这是我最终得到的gulpfile.js

    npm install gulp url proxy-middleware browser-sync --save-dev

    // Include gulp
    var gulp = require('gulp');
    
    var url = require('url');
    var proxy = require('proxy-middleware');
    var browserSync = require('browser-sync'); 
    
    var paths =  {
        css: ['./**/*.css', '!./node_modules/**/*']
    };
    
    
    // browser-sync task for starting the server.
    gulp.task('browser-sync', function() {
        var proxyOptions = url.parse('http://localhost:3000/secret-api');
        proxyOptions.route = '/api';
        // requests to `/api/x/y/z` are proxied to `http://localhost:3000/secret-api/x/y/z`
    
        browserSync({
            open: true,
            port: 3000,
            server: {
                baseDir: "./",
                middleware: [proxy(proxyOptions)]
            }
        });
    });
    
    // Stream the style changes to the page
    gulp.task('reload-css', function() {
        gulp.src(paths.css)
            .pipe(browserSync.reload({stream: true}));
    });
    
    // Watch Files For Changes
    gulp.task('watch', function() {
        gulp.watch(paths.css, ['reload-css']);
    });
    
    // Default Task
    gulp.task('default', ['browser-sync', 'watch']);
    

    如果您不想创建单独的 gulp 任务来重新加载/流式传输更改,您可以使用 files option:

    browserSync({
        open: true,
        port: 3000,
        server: {
            baseDir: "./",
            middleware: [proxy(proxyOptions)]
        },
        files: paths.css
    });
    

    【讨论】:

    • @pjv 给我一个 url 的例子。这对我来说很好用:http://localhost:3000/secret-api/a/b/c/index.html?asfd
    • browsersync 正在为一个需要 POST 到烧瓶网络应用程序的静态站点提供服务。该烧瓶应用程序也在我的开发机器上运行在与 browsersync 不同的端口上。 browsersync 在端口 3000 上运行,flask 在 4000 上运行。所以我想将看起来像 /charge(完整 url:http://localhost:3000/charge)的路径路由到 http://localhost:4000/charge
    • @pjv 这行得通吗:var proxyOptions = url.parse('http://localhost:4000/charge'); proxyOptions.route = '/charge';。如果您需要进一步的帮助,我建议我们借此聊天。
    • 不,这不起作用 - 这正是我在 gulpfile.js 中所拥有的。当我提交表单时,烧瓶应用程序没有任何反应。如果我将路线更改为/charge/(斜杠),那么它会命中烧瓶应用程序,但烧瓶应用程序正在寻找/charge 而不是/charge/ 所以它是404。
    • 我只是面临与斜杠相同的问题。如果它在 url 中不存在,则代理不起作用。这仅适用于基本网址。即使没有斜线,嵌套 url 也能正常工作。您是否以某种方式解决了这个问题?
    【解决方案2】:

    在从 grunt 迁移到 gulp 时,我在 gulp + browser-sync + proxy-middleware 设置中遇到了同样的问题。

    Error: connect ECONNREFUSED
        at errnoException (net.js:904:11)
        at Object.afterConnect [as oncomplete] (net.js:895:19)
    

    在我的情况下,公司网络中的某些东西不允许代理中间件工作。我一上公共网络,问题就消失了。

    使用 grunt-connect + grunt-connect-proxy,我可以毫无问题地代理公司网络内的文件。

    proxy-middleware 实现自己的代理功能,而 grunt-connect-proxy 使用 http-proxy 来完成实际的代理工作。

    我最终围绕 http-proxy 编写了一个小型中间件包装器,用于浏览器同步和连接,这解决了公司网络中的代理问题。

    https://www.npmjs.com/package/http-proxy-middleware

    var browserSync = require('browser-sync');
    var proxyMiddleware = require('http-proxy-middleware');
    
    var proxy = proxyMiddleware('/ajax', {target: 'http://cdnjs.cloudflare.com'});
    
    browserSync({
        server: {
            baseDir: "./",
            port: 3000,
            middleware: [proxy]
        }
    });
    

    【讨论】:

    • 那个中间件太棒了,干得好!
    • @Tropicalista 如果您认为发现了错误,请在以下地址创建票证:github.com/chimurai/http-proxy-middleware/issues
    • 如何检查它是否正常工作?我配置了代理,但在网络/请求 URL 标头中我没有看到代理 URL。只有我的主机的 URL,谢谢)
    【解决方案3】:

    我遇到了一个问题,我找不到解决方案。我需要两种选择:

    1. browser-sync 运行在SPA mode
    2. /api 路由上有middleware 代理

    SPA 模式似乎拦截了/api 并呈现index.html 而不是代理到后端。

    解决方案在browser-syncsources:使用middleware路由实现单模式,比手动添加的优先级更高:

            if (bs.options.get("single")) {
                defaultMiddlewares.unshift({
                    id: "Browsersync SPA support",
                    route: "",
                    handle: require("connect-history-api-fallback")()
                });
            }
    

    以下配置根据需要工作 - SPA 路由位于中间件列表的末尾:

    const proxy = require('proxy-middleware');
    ...
        server.init({
            ...
            middleware: [ {
                route: "/api",
                handle: proxy(url.parse("http://api.host:4444/api"))
            }, {
                id: "SPA support",
                route: "",
                handle: require("connect-history-api-fallback")()
            } ],
            single: false,
            ...
        })
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-15
      • 1970-01-01
      • 1970-01-01
      • 2017-03-22
      • 1970-01-01
      • 1970-01-01
      • 2016-04-22
      • 1970-01-01
      相关资源
      最近更新 更多