javascript - 在 Browsersync 中手动重写对特定 URL 的请求

标签 javascript express browser-sync

我在一个有点奇怪的设置中使用 BrowserSync,其中我代理我的 Web 服务器(Docker 容器中的 Apache),但也从 Webpack 开发服务器提供热模块替换 (HMR)。

在我的本地开发环境中,设置如下所示:

https://mytestsite.localhost – Docker 容器中的 Apache 服务

https://localhost:8888 – Webpack 开发服务器,服务 HMR

https://localhost:3000 – BrowserSync`

对于硬重新加载,这一切都工作正常 - webpack 开发服务器似乎传递了需要重新加载的消息,一切都很好。

我遇到的问题是热重载。 BS 代理提供的文档应该读取 webpack-dev-server 提供的 hotupdate.json。收到热更新后,页面会尝试加载 /hotupdate.json (我相信它告诉它要选取哪个代码片段),但是,因为它是相对 URL,所以浏览器会尝试 GET https://localhost:3000/hotupdate.json,即 404,因为这个 hotupdate.json 实际上是由 Webpack 服务器提供服务的,例如https://localhost:8888/hotupdate.json

因为我知道此资源的绝对 URL,所以我想强制 BrowserSync 将任何对 /hotupdate.json 的请求重定向到 https://localhost:8888/hotupdate。 json.我以为我可以用一些中间件来做到这一点,但我很挣扎,可能是因为我从未完全理解 Express 风格的中间件。

我已经尝试过类似的方法,但不起作用!

browserSync({
    proxy: {
        target: `https://${process.env.APP_HOST_PATH}`,
        middleware: [
            dontProxyHotUpdate,
            require('webpack-dev-middleware')(bundler, {
                noInfo: true,
                publicPath: webpackConfig.output.path
            }),
        ]
    },
    files: [
      'app/css/*.css',
      'app/*.html'
    ]
});

function dontProxyHotUpdate (req, res, next){
    if(req.url === '/hotupdate.json'){
        req.url = 'https://127.0.0.1:8888/hotupdate.json';
    }
    next();
}

它肯定会加载中间件,就像我可以的那样,console.log(req.url),但我无法重写请求 URL。我想可能的解决方案是重写请求 URL,或者直接覆盖响应。

注意有人可能会问为什么我不直接使用 webpack-dev-server,因为它本身就可以很好地服务 HMR。确实如此,但它也不允许对页面内的 anchor 元素进行良好的重写,例如将 https://mytestsite.localhost/link 更改为 https://localhost:3000/link 。这对于在开发时浏览网站显然很重要(这很好,但不是必需的),但对于重写 Assets 链接更重要 - 特别是 SVG,除非路径、主机和端口全部匹配,否则不会加载.

最佳答案

好吧,最后我解决了我自己的问题!

我最终使用 http-proxy-middlware 编写了自己的中间件 - 像这样。

var proxy = require('http-proxy-middleware');

browserSync({
    proxy: {
        target: `https://${process.env.APP_HOST_PATH}`,
        middleware: [
            dontProxyHotUpdate,
            require('webpack-dev-middleware')(bundler, {
                noInfo: true,
                publicPath: webpackConfig.output.path
            }),
            // require("webpack-hot-middleware")(bundler) // I don't think that we want this here as it can be handled by the webpack dev server
        ],
    },

    // no need to watch '*.js' here, webpack will take care of it for us,
    // including full page reloads if HMR won't work
    files: [
      path.join(source, '**/*.php'),
      path.join(source, 'style.css')
    ]
});

var dontProxyHotUpdate = proxy('/hotupdate*', {
    target: 'https://127.0.0.1:8888/',
    changeOrigin: true, // for vhosted sites, changes host header to match to target's host
    logLevel: 'debug',
    secure: false
});

关于javascript - 在 Browsersync 中手动重写对特定 URL 的请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39526547/

相关文章:

javascript - 选择DataTable中一行的按钮

Gulp 浏览器同步管道不工作

javascript - BrowserSync 突然无法连接到浏览器

javascript - Knockout js可见绑定(bind)似乎不起作用

javascript - 检测 HTML select 元素是否展开(无需手动跟踪状态)

node.js - 为 Node.js 重写 PHP URL

javascript - 对象 SequelizeInstance 被传递

javascript - gulp - 如何停止或取消任务运行

javascript - 是否可以使用 JavaScript 方法来处理未定义的属性?

匹配 url 模式的 Node.js