Serving React application hoping through servers and using iframe

I have a scenario where I have two React applications. Application-1 opens Application-2 using an iframe.

I can access Application-2 either directly or through the Application-1 iframe. However, when I use the Application-1 iframe, it must go through multiple server hops to reach Application-2, something like the following.

Application-1 —-> Express-Server-1(serving Application-1 & forwarding request for Application-2) —-> Express-Server-2(proxy/passthrough) ——> Express-Server-3(serving Application-2)—–> Application-2

while I can access Application-2 directly I can’t access using Application-1 using an Iframe.

so below is the app.js file which serves the Application-2 and is running on server-3.

const createError = require("http-errors");
const express = require("express");
const cors = require('cors')
const path = require("path");
const fs = require("fs");
const cookieParser = require("cookie-parser");

// Server-static middleware
const {
    appLogger,
    expressLogger,
    expressErrorLogger,
} = require("./lib/logger");

const {corsOptionsDelegate} = require("./routes/corsDelegate");
const app = express();

app.disable("x-powered-by");
app.options('*', cors());
// serves static pages
app.use("/application-2/static", express.static(path.join(__dirname, "public")));

// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "jade");

app.use(express.json());
app.use(express.urlencoded({extended: false}));
app.use(expressLogger);
app.use(expressErrorLogger);
app.use(cookieParser());

app.use(
    express.static(path.join(__dirname, ".", "webapp")),
    (req, res, next) => {
        try {
            decodeURIComponent(req.url);
            return next();
        } catch (err) {
            return res.status(400).json({message: "Invalid request"});
        }
    }
);

const managementRouter = require("./routes/management");
app.use("/application-2/management", managementRouter);

// serves the application-2 app
app.use("/application-2", express.static(path.join(__dirname, ".", "webapp")));

// connect to the "src/routes" directory
const routersPath = path.join(__dirname, "routes/v1");
// read all files in the "/src/routers" directory
fs.readdirSync(routersPath).forEach((file) => {
    if (file.endsWith(".js")) {
        // dynamically import the router module
        const routerModule = require((path.join(routersPath, file).replace(".js","")));
        // register the router
        app.use(routerModule);
    }
});

app.get("/application-2/unauthorized", cors(corsOptionsDelegate), function (req, res, next) {
    res.status(403);
    res.sendFile(path.resolve(__dirname, ".", "views", "unauthorized.html"));
});

// catch 404 and forward to error handler
app.use(function (req, res, next) {
    next(createError(404));
});

// error handling
app.use(function (err, req, res, next) {
    // set locals, only providing error in development
    res.locals.message = err.message;
    res.locals.error = req.app.get("env") === "development" ? err : {};

    // render the error page
    res.status(err.status || 500);
    res.render("error", {title: "ABC Images | application Search"});
});

module.exports = app;

below is code at server-1 to fetch application-2, i.e when application-1 opens iframe it makes a call to server-1 at /application-search.

app.use("/application-search", createProxyMiddleware({
  target: "http://localhost:9012",
  changeOrigin: true,
  logLevel: 'debug',
  pathRewrite: (path, req) => {
    // Extract the query string from the original URL
    const queryString = req.url.split('?')[1] || "11x";
    // Rewrite the path to include the query string
    return `/?${queryString}`;
  },
  onProxyReq: (proxyReq, req, res) => {
    let cookieArray = [];
    try {
      // Split the cookies into an array and log them
      const cookies = req.headers.cookie || "";
      cookieArray = cookies.split(';').map(row => {
        return row.trim();
      });
    } catch (error) {
      console.error('Error processing cookies:', error);
    }
    //const tokenCookie = cookieArray.find(row => row.startsWith('ckns_pp_id=')) || "";
    const tokenValue = tokenCookie.split('=')[1].trim();

    // Add custom headers if needed
    proxyReq.setHeader('Authorization', `Bearer ${tokenValue}`);
  }

}));

below is code at server-2 which when get request from server-1 will hit the server-3 that is serving application-2

app.use("/", createProxyMiddleware({
  target: "https://xxx.co.uk/application-2",
  changeOrigin: true,
  logLevel: 'debug',
  pathRewrite: (path, req) => {
    // Extract the query string from the original URL
    const queryString = req.url.split('?')[1] || "11x";
    // Rewrite the path to include the query string
    return `/?${queryString}`;
  },
  onProxyReq: (proxyReq, req, res) => {
    // Add the authorization header
    const bearerToken = req.headers['authorization'] || "";
    proxyReq.setHeader('Authorization', bearerToken);
  },
  onProxyRes: (proxyRes, req, res) => {
    console.log(`⬅️ Response from Server-3: ${proxyRes.statusCode} for ${req.url}`);
  }
}));

I am either getting 404 not find “Not Found, when from application-1 I try to open iframe to show application-2

404
NotFoundError: Not Found
    at /Users/abc01/projects/application-2/server/app.js:104:10

Currently I am using createProxyMiddleware strategy to pass on the request, please do advise if there is a better strategy for this requirements, as I have to hop though the servers as there are some authentication requirements and can’t access the application-2 directly.