在 Spring Boot 服务器和 Angular 应用程序中使用 URL 重写时出现 MIME 类型错误

MIME types error when using URL rewriting on Springboot server and Angular app

我正在开发一个带有 2 个 Angular 应用程序前端的 SpringBoot 应用程序,它们的位置如下:
Springboot 应用程序:src -> main -> java
Angular 应用程序 1(fo):src -> main -> resources -> public -> fo
Angular 应用程序 2(博):src -> main -> resources -> public -> bo

注意:在 angular 应用程序的根文件夹中可以找到一些文件,例如 index.htmlruntime-es[...].js(以及其他文件)

所以我为我的 Springboot 应用创建了一个 Controller class :

@Controller
public class MainController {

    @GetMapping("/fo")
  public String index() {
      return "/fo/index.html";
  }

  @GetMapping("/bo")
  public String admin() {
      return "/bo/index.html";
  }
}

还有一个Configuration class :

@Configuration
@ComponentScan(basePackageClasses = {MainApplicationImpl.class})
@EnableWebSecurity
public class PresentationConfiguration extends WebSecurityConfigurerAdapter implements WebMvcConfigurer {

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().antMatchers("/**").permitAll();
  }

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/fo/**")
      .addResourceLocations("classpath:/public/fo/")
      .resourceChain(true)
      .addResolver(new PathResourceResolver() {
        @Override
        protected Resource getResource(String resourcePath, Resource location) throws IOException {
          Resource requestedResource = location.createRelative(resourcePath);

          return requestedResource.exists() && requestedResource.isReadable() ? requestedResource
            : new ClassPathResource("/public/fo/index.html");
        }
      });

    registry.addResourceHandler("/bo/**")
      .addResourceLocations("classpath:/public/bo/")
      .resourceChain(true)
      .addResolver(new PathResourceResolver() {
        @Override
        protected Resource getResource(String resourcePath, Resource location) throws IOException {
          Resource requestedResource = location.createRelative(resourcePath);

          return requestedResource.exists() && requestedResource.isReadable() ? requestedResource
            : new ClassPathResource("/public/bo/index.html");
        }
      });
  }

想法是 fo 应该可以在互联网上使用,例如 http://www.fo.com/,而 bo 只能在我客户的内部网络上使用,假设 http://client.bo.internal/.

为了模拟这一点,我设置了某种“reverse_proxy”,使用 docker 和 Caddy 重写 URL,这里是 url 重写的示例的 bo

Caddyfile

localhost:80 {
    route /* {
        rewrite /* /bo/*
        reverse_proxy http://host.docker.internal:8081
    }
}

docker-compose.yml

version: '3'
services:
  proxy:
    image: caddy
    #command
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
    ports:
      - '8082:80'

这样,当我在网络浏览器上键入 http://localhost:8082 时,它会这样调用我的 Springboot 应用程序:http://localhost:8081/bo.
这个 kinda 有效,因为我在页面上显示了 index.html 文件,但是每个指向 js 文件和 css 文件的链接都出现错误显示

Failed to load module script: The server responded with a non-JavaScript MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.

以下是我在浏览器开发工具中看到的一些截图:

HTML http://localhost:8082 的内容:

控制台错误:

网络选项卡:

这里有一些有趣的事情,每个文件似乎都有 index.html 的内容:

由于问题似乎来自 MIME 类型,我如何指定从 .html 文件调用的 .js 文件不是 text/html 而是 application/javascript(如果它真的是我的问题)?

根据我在 Internet 上找到的有关此错误的信息,可以通过重写 <base href="/" /> 标记来修复它。但我 不想 这样做,因为这意味着 URL 必须是 http://localhost/fo/.

希望你能帮助我,感谢阅读!

找到了解决这个问题的方法,错误显示是因为我的 CaddyFile 配置。使用 url replace 而不是 rewrite.

新 CaddyFile :

localhost:80 {
    route /* {
        uri replace / /bo/ 1
        reverse_proxy http://host.docker.internal:8081
    }
}

这会将第一次出现的 / 替换为 /bo/,所以我调用 http://localhost:8082/ 并得到 http://localhost:8081/bo/。您可能希望 rewriting 语法能够做到这一点,但显然不是。