在 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.html
和 runtime-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
语法能够做到这一点,但显然不是。
我正在开发一个带有 2 个 Angular 应用程序前端的 SpringBoot 应用程序,它们的位置如下:
Springboot 应用程序:src -> main -> java
Angular 应用程序 1(fo):src -> main -> resources -> public -> fo
Angular 应用程序 2(博):src -> main -> resources -> public -> bo
注意:在 angular 应用程序的根文件夹中可以找到一些文件,例如 index.html
和 runtime-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
语法能够做到这一点,但显然不是。