5

I'm trying to redirect API calls from my Static Web App to another Function App but I can't get wildcard to work.

The route matches correctly but I want the * part to be included in the redirect. This is an example from my staticwebapp.config.json

  {
        "route": "/api/client/*",
        "redirect": "https://xx.yy.net/api/client/*"
  }

I would like the request /api/client/customer/get?customerId=xx to become https://xx.yy.net/api/client/customer/get?customerId=xx.

But whatever I try it only hard routes to exactly what I put in the redirect. With functions this is possible with a proxy but I can't find a way in a Static Web App.

ragazzojp
  • 477
  • 3
  • 14
Pulka
  • 51
  • 1

2 Answers2

0

A bit late, but in my case it was possible to get the original Url from a header:

        if (shortUrl == "*")
        {
            var original = req.Headers
                .FirstOrDefault(h => h.Key.ToLower() == "x-ms-original-url")
                .Value.FirstOrDefault()?.ToString();
            if (string.IsNullOrWhiteSpace(original))
            {
                shortUrl = "";
            }
            else
            {
                shortUrl = original.Split("/")
                    .Where(p => !string.IsNullOrWhiteSpace(p))?
                    .LastOrDefault() ??"";
            }
        }
Mcafee
  • 21
  • 3
0

There's a way using dynamic redirects powered by the inbuilt function app. Your staticwebapp.config.json needs this:

"navigationFallback": {
    "rewrite": "/api/fallback"
  }

and a fallback function to handle the redirect; something like this:

//@ts-check
const { parseURL } = require('ufo');
const routes = require('./redirects');

/**
 *
 * @param { import("@azure/functions").Context } context
 * @param { import("@azure/functions").HttpRequest } req
 */
async function fallback(context, req) {
  const originalUrl = req.headers['x-ms-original-url'];
  if (originalUrl) {
    // This URL has been proxied as there was no static file matching it.
    context.log(`x-ms-original-url: ${originalUrl}`);

    const parsedURL = parseURL(originalUrl);

    const matchedRoute = routes.find((route) =>
      parsedURL.pathname.includes(route.route)
    );

    if (matchedRoute) {
      context.log(`Redirecting ${originalUrl} to ${matchedRoute.redirect}`);

      context.res = {
        status: matchedRoute.statusCode,
        headers: { location: matchedRoute.redirect },
      };
      return;
    }
  }

  context.log(
    `No explicit redirect for ${originalUrl} so will redirect to 404`
  );

  context.res = {
    status: 302,
    headers: {
      location: originalUrl
        ? `/404?originalUrl=${encodeURIComponent(originalUrl)}`
        : '/404',
    },
  };
}

module.exports = fallback;

You get a lot of flexibility here to implement any solution you desire; including wildcards

There's a more in depth explanation here: https://johnnyreilly.com/2022/12/22/azure-static-web-apps-dynamic-redirects-azure-functions

John Reilly
  • 5,791
  • 5
  • 38
  • 63