Spring Boot+Thymeleaf部署Angular应用:JS文件解析错误求助
我正尝试使用Spring Boot/Thymeleaf部署Angular应用,负责分发HTML/CSS/JavaScript文件的控制器类代码如下:
@Controller public class ResourceProvider { @RequestMapping(method = RequestMethod.GET, value = "/") public String root() { return "index"; } @RequestMapping(method = RequestMethod.GET, value = "/{css}.css") public String css(@PathVariable(value = "css") String css, Model model) { return css + ".css"; } @RequestMapping(method = RequestMethod.GET, value = "/{js}.js") public String js(@PathVariable(value = "js") String js, Model model) { return js + ".js"; } }
所有文件均可正常被找到,但当index.html请求JavaScript文件(尤其是main和polyfills)时,Thymeleaf抛出解析错误:
org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression: "Zone_symbol_prefix||"" (template: "polyfills.718fa2660ef118dd.js" - line 1, col 89) org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression: "source";let xi;function Tr(t){const e=xi;return xi=t,e}function TC(t,e=x.Default){if(void 0===xi)throw new D(-203,!1);return null===xi?Ah(t,void 0,e):xi.get(t,e&x.Optional?null:void 0,e)}function C(t,e=x.Default){return(function CC(){return Vl}()||TC)(O(t),e)}function G(t,e=x.Default){return C(t,ho(e))}function ho(t){return typeof t>"u"||"number"==typeof t?t:0|(t.optional&&8)|(t.host&&1)|(t.self&&2)|(t.skipSelf&&4)}function zl(t){const e=[];for(let n=0;n<t.length;n++){const r=O(t[n]);if(Array.isArray(r)){if(0===r.length)throw new D(900,!1);let i,s=x.Default;for(let o=0;o<r.length;o++){const a=r[o],l=MC(a);"number"==typeof l?-1===l?i=a.token:s|=l:i=a}e.push(C(i,s))}else e.push(C(r))}return e}function Fi(t,e){return t[Hl]=e,t.prototype[Hl]=e,t}function MC(t){return t[Hl]}function Fn(t){return{toString:t}.toString()}var At=(()=>((At=At||{})[At.OnPush=0]="OnPush",At[At.Default=1]="Default",At))(),Rt=(()=>{return(t=Rt||(Rt={}))[t.Emulated=0]="Emulated",t[t.None=2]="None",t[t.ShadowDom=3]="ShadowDom",Rt;var t})();const un={},X=[],po=ne({ɵcmp:ne}),Gl=ne({ɵdir:ne}),ql=ne({ɵpipe:ne}),Ph=ne({ɵmod:ne}),cn=ne({ɵfac:ne}),ki=ne({" (template: "main.b51697c6f79772d3.js" - line 1, col 89)
我的JS文件中无需解析任何变量,仅需直接发送给客户端,请问是否有办法让JavaScript文件不经过Thymeleaf处理?
解决方案
1. 利用Spring Boot默认静态资源目录(推荐)
Spring Boot会自动加载src/main/resources/static、src/main/resources/public等目录下的静态资源,无需通过Controller转发。你可以把Angular打包后的CSS、JS文件放到src/main/resources/static,HTML文件保留在src/main/resources/templates(Thymeleaf默认模板目录)。
修改后的Controller只需保留根路径处理:
@Controller public class ResourceProvider { @RequestMapping(method = RequestMethod.GET, value = "/") public String root() { return "index"; } }
此时访问JS/CSS资源时,Spring Boot会直接返回文件内容,不会经过Thymeleaf解析。
2. 修改Controller直接返回资源文件
如果不想调整文件目录,可修改Controller中处理JS/CSS的方法,直接返回文件资源,绕过Thymeleaf模板解析:
@Controller public class ResourceProvider { @RequestMapping(method = RequestMethod.GET, value = "/") public String root() { return "index"; } @GetMapping("/{css}.css") public ResponseEntity<Resource> css(@PathVariable String css) { // 替换为你的CSS文件实际路径 Resource resource = new ClassPathResource("templates/" + css + ".css"); return ResponseEntity.ok() .contentType(MediaType.TEXT_CSS) .body(resource); } @GetMapping("/{js}.js") public ResponseEntity<Resource> js(@PathVariable String js) { // 替换为你的JS文件实际路径 Resource resource = new ClassPathResource("templates/" + js + ".js"); return ResponseEntity.ok() .contentType(MediaType.APPLICATION_JAVASCRIPT) .body(resource); } }
3. 配置Thymeleaf忽略特定后缀文件
在application.properties中添加配置,让Thymeleaf不解析.js和.css后缀的文件:
spring.thymeleaf.excluded-view-names=*.js,*.css
这样当Controller返回xxx.js或xxx.css时,Thymeleaf会直接返回对应文件内容,不进行模板解析。
内容的提问来源于stack exchange,提问作者Cole White

