0

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

注意:在 Angular 应用程序的根文件夹中,index.html可以runtime-es[...].js找到一些类似的文件(以及其他文件)

所以我Controller为我的 Springboot 应用程序创建了一个类,如下所示:

@Controller
public class MainController {

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

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

以及一个Configuration类:

@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

球童档案

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

码头工人-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
有点工作,因为我正在页面上显示 index.html 文件,但是每个指向 js 文件和 css 文件的链接都显示错误

加载模块脚本失败:服务器以“text/html”的非 JavaScript MIME 类型响应。根据 HTML 规范对模块脚本强制执行严格的 MIME 类型检查。

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

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

控制台中的错误: 控制台中的错误

网络选项卡: 网络选项卡

这是一些有趣的事情,每个文件似乎都有以下内容index.html一些 .js 文件的内容

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

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

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

4

1 回答 1

0

找到了解决此问题的方法,由于我的 CaddyFile 的配置而显示错误。使用url replace代替rewrite

新球童文件:

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

这将取代第一次出现的/to /bo/,所以我打电话http://localhost:8082/并得到 http://localhost:8081/bo/。您会期望rewriting语法完全做到这一点,但显然不是。

于 2020-11-26T11:09:01.217 回答