webpack dev-server:避免代理错误返回代理目标返回的HTTP错误

时间:2019-02-13 17:53:10

标签: vue.js webpack webpack-dev-server http-proxy

我有一个Vue.js项目,在其中配置了一个webpack开发服务器,以将对UI的所有请求代理到我的后端服务器。这是vue.config.js的相关部分:

devServer: {
    contentBase: PATHS.build,
    port: 9000,
    https: false,
    hot: true,
    progress: true,
    inline: true,
    watchContentBase: true,
    proxy: {
        '^/': {
            target: 'http://127.0.0.1:8089',
            secure: false
        },
    }
},

我注意到,如果http://127.0.0.1:8089的HTTP响应代码不是2xx,则代理将失败,并显示以下错误:

  

代理错误:无法将请求/ api / test从localhost:9000代理到http://127.0.0.1:8089。   有关更多信息,请参见https://nodejs.org/api/errors.html#errors_common_system_errors(HPE_INVALID_CHUNK_SIZE)。

对于任何错误,这还会导致从请求到localhost:9000的HTTP响应代码为500,并且有关服务器端发生问题的所有信息都将丢失。这是有问题的,因为我希望能够从错误响应中提取信息以显示给用户。

我知道这是可能的,因为我在一个较旧的Angular项目上工作,我认为它使用的是Webpack 3(现在使用Webpack 4)。我尝试从该项目中复制所有dev-server配置,但似乎在这里不起作用!

编辑:我错了。代理错误不会在每个错误的响应上发生,而只会出现在多文件上传的请求中。仍然无法在一个较小的示例中重现此问题,以使其放在github上,尽管如此难以找出原因。

2 个答案:

答案 0 :(得分:2)

我终于找到了问题,对不起,这是一个比我写这个问题时最初想的要具体得多的问题。

问题与使用Spring RestTemplate代理到另一个服务器的请求有关:

例如

@PostMapping("/upload")
    public ResponseEntity upload(@RequestParam("file") MultipartFile file)
        throws Exception {
        String baseUrl = serviceProperties.getAddress();
        HttpEntity<MultiValueMap<String, Object>> request = createMultipartRequest(file.getBytes());
        return restTemplate.postForEntity(baseUrl + "/api/upload", filterRequest, String.class);
    }

从其余模板代理返回的ResponseEntity包含标头“ Connection:close”(当响应不是200时,它导致连接关闭并导致该请求无法返回任何内容,从而使开发服务器代理不成功)在用户界面上失败。

通过不将响应头从其余模板代理传递到响应来解决此问题:

@PostMapping("/upload")
    public ResponseEntity upload(@RequestParam("file") MultipartFile file)
        throws Exception {
        String baseUrl = serviceProperties.getAddress();
        HttpEntity<MultiValueMap<String, Object>> request = createMultipartRequest(file.getBytes());
        ResponseEntity response = restTemplate.postForEntity(baseUrl + "/api/upload", filterRequest, String.class);
        return new ResponseEntity<>(response.getBody(), response.getStatusCode());
    }

答案 1 :(得分:0)

此错误消息来自node_modules/@vue/cli-service/lib/util/prepareProxy.js,它为node-http-proxy定义了onError回调;

所以我做了一些实验,使后端api生成400404500响应,但是我没有出现此错误。

我碰巧关闭后端api后,出现错误:

Proxy error: Could not proxy request /hello from localhost:8080 to http://localhost:8081 (ECONNREFUSED).

我在the doc中搜索并找到了这些

  

如果对目标的请求失败,则发出错误事件。我们不对客户端和代理之间传递的消息以及代理和目标之间传递的消息进行任何错误处理,因此建议您侦听错误并进行处理

因此,onError不处理错误代码,仅在请求失败时被调用({500 response仍被视为完整请求,connection refuse未被视为完整请求)


返回您的错误消息,[HPE_INVALID_CHUNK_SIZE]表示对后端api的请求不正确。在this issue中,它提供了一个解决方案:add a keep-alive header

devServer: {
    publicPath: 'http://localhost:9090/front/static-dev/build/',
    port: 9090,
    proxy: {
        '/**': {
            target: 'http://localhost:8080',
            secure: false,
            changeOrigin: true,
            headers: {
                   Connection: 'keep-alive'
            }
    },
    open: true
}