javascriptproxywebpack-dev-server

Webpack Dev Server Proxy Is Ignored


I have webpack dev server running on http://localhost:8080 and an express server running on https://localhost:443. I'm proxying to :443 in my webpack dev server config. My express server works fine with Postman but when I make a fetch request from :8080, I get 400 (Bad Request). When I print the response, response.url is still http://localhost:8080.

I've been through several other posts and have tried the following config:

When running webpack dev server, I see Proxy created: /api -> https://localhost:443 in the terminal. What am I missing?

My webpack dev server config looks like this:

    devServer: {
        hot: true,
        proxy: {
            '/api': {
                target: 'https://localhost:443',
                secure: false,
                changeOrigin: true
            },
            logLevel: 'debug'
        }
    }

My fetch request looks like this:

        var response = await fetch('/api/create_link_token', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: { idToken },
                url: 'https://localhost:443'
            }),
            data = await response;
            console.log(response); // response.url is http://localhost:8080/api/create_link_token

Solution

  • Your code has some issues:

    1. No url option exists for the fetch function.

    2. The HTTP request URL should be http://localhost:8081/api/create_link_token, in this way, the HTTP proxy middleware will proxy the /api to https://localhost:8443.

    3. The body accepts a JSON string, like JSON.stringify({ idToken: 1 }).

    Below is a working example:

    client/src/index.js:

    function main() {
        fetch('/api/create_link_token', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ idToken: 1 }),
        })
            .then((res) => res.json())
            .then((data) => console.log('data: ', data));
    }
    
    main();
    

    client/webpack.config.js:

    const path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    
    module.exports = {
        mode: 'development',
        entry: './src/index.js',
        output: {
            path: path.resolve(__dirname, 'dist'),
            clean: true,
        },
        devServer: {
            hot: true,
            proxy: {
                '/api': {
                    target: 'https://localhost:8443',
                    secure: false,
                    changeOrigin: true,
                },
            },
        },
        plugins: [
            new HtmlWebpackPlugin({
                template: path.resolve(__dirname, 'src/index.html'),
            }),
        ],
    };
    

    server/app.js:

    const express = require('express');
    const fs = require('fs');
    const path = require('path');
    const http = require('http');
    const https = require('https');
    
    const app = express();
    app.use(express.json());
    
    app.post('/api/create_link_token', (req, res) => {
        console.log(req.body);
        res.status(200).json({ code: 0 });
    });
    
    app.get('/ok', (req, res) => {
        res.sendStatus(200);
    });
    
    const serverOptions = {
        key: fs.readFileSync(path.resolve(__dirname, './ssl/key.pem')),
        cert: fs.readFileSync(path.resolve(__dirname, './ssl/cert.pem')),
    };
    
    const httpServer = http.createServer(app);
    const httpsServer = https.createServer(serverOptions, app);
    
    httpServer.listen(8080);
    httpsServer.listen(8443);
    

    Start the webpack dev server by running webpack serve, logs:

    > webpack serve
    
    <i> [webpack-dev-server] [HPM] Proxy created: /api  -> https://localhost:8443
    <i> [webpack-dev-server] Project is running at:
    <i> [webpack-dev-server] Loopback: http://localhost:8081/
    <i> [webpack-dev-server] On Your Network (IPv4): http://192.168.10.197:8081/
    <i> [webpack-dev-server] Content not from webpack is served from 'D:\workspace\mrdulin\webpack-samples\webpack-v5\stackoverflow\77877176\client\public' directory
    asset main.js 265 KiB [emitted] (name: main)
    asset index.html 297 bytes [emitted]
    runtime modules 27.2 KiB 12 modules
    modules by path ./node_modules/ 177 KiB
      modules by path ./node_modules/webpack-dev-server/client/ 71.8 KiB 16 modules
      modules by path ./node_modules/webpack/hot/*.js 5.18 KiB
        ./node_modules/webpack/hot/dev-server.js 1.94 KiB [built] [code generated]
        ./node_modules/webpack/hot/log.js 1.74 KiB [built] [code generated]
        + 2 modules
      modules by path ./node_modules/html-entities/lib/*.js 81.8 KiB
        ./node_modules/html-entities/lib/index.js 7.91 KiB [built] [code generated]
        ./node_modules/html-entities/lib/named-references.js 73 KiB [built] [code generated]   
        ./node_modules/html-entities/lib/numeric-unicode-map.js 339 bytes [built] [code generated]
        ./node_modules/html-entities/lib/surrogate-pairs.js 537 bytes [built] [code generated] 
      ./node_modules/ansi-html-community/index.js 4.16 KiB [built] [code generated]
      ./node_modules/events/events.js 14.5 KiB [built] [code generated]
    ./src/index.js 254 bytes [built] [code generated]
    webpack 5.90.1 compiled successfully in 533 ms
    

    Refresh the HTML page multiple times, the logs of the server:

    { idToken: 1 }
    { idToken: 1 }
    { idToken: 1 }
    

    The logs in the browser console:

    enter image description here