启用URL重写的WebLogic部署Angular4应用刷新/直访先出404问题求助
我之前帮不少开发者解决过类似的Angular路由在WebLogic上的问题,你遇到的这个“首次请求出现404”本质是因为HTML5模式路由的特性,加上之前的404重定向是事后补救,而不是提前转发导致的。下面给你一套彻底解决的方案:
核心原因分析
Angular的HTML5模式路由(非Hash模式)下,当你直接访问/dashboard这类路由URL时,浏览器会向WebLogic发送真实的HTTP请求。WebLogic会去寻找服务器上是否存在/dashboard这个物理文件或资源,找不到就返回404,之后才会触发你的404重定向规则跳转到index.html。所以网络请求里必然会先出现那个404记录。
要解决这个问题,我们需要让WebLogic在返回404之前,就把所有非静态资源的请求直接转发到index.html,由Angular的路由系统来处理。
具体解决方案
1. 确保Angular项目的路由配置正确
首先确认你的Angular项目已经启用了HTML5模式:
- 在
app-routing.module.ts(或对应的路由模块)中,设置useHash: false:
import { RouterModule, Routes } from '@angular/router'; const routes: Routes = [ // 你的路由定义,比如 { path: 'dashboard', component: DashboardComponent } ]; @NgModule({ imports: [RouterModule.forRoot(routes, { useHash: false, // 启用HTML5模式 enableTracing: false // 生产环境建议关闭 })], exports: [RouterModule] }) export class AppRoutingModule { }
- 在
index.html的<head>标签内添加<base href="/">,确保路由路径正确解析:
<head> <base href="/"> <!-- 其他meta、样式等 --> </head>
2. 配置WebLogic的URL重写规则(关键步骤)
WebLogic 12c及以上版本支持原生的URL重写模块,我们可以通过配置rewrite.xml和web.xml来实现请求转发:
步骤2.1 创建WEB-INF/rewrite.xml文件
在你的Web应用的WEB-INF目录下新建rewrite.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <rewrite-config xmlns="http://xmlns.oracle.com/weblogic/rewrite/config"> <!-- 规则:所有不是静态资源的请求,都转发到index.html --> <rule> <!-- 正则匹配:排除.js/.css/.png等静态文件,避免Angular的静态资源被转发 --> <from>^/(?!.*\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$).*</from> <!-- 转发到index.html,注意是forward(内部转发)不是redirect(重定向) --> <to type="forward">/index.html</to> </rule> </rewrite-config>
这个正则表达式会排除所有常见的静态资源后缀,确保只有路由请求会被转发到index.html。
步骤2.2 修改WEB-INF/web.xml启用重写
在web.xml中添加重写的监听器和过滤器配置:
<!-- 添加重写监听器 --> <listener> <listener-class>com.oracle.webapps.listeners.RewriteListener</listener-class> </listener> <!-- 添加重写过滤器 --> <filter> <filter-name>RewriteFilter</filter-name> <filter-class>com.oracle.webapps.filters.RewriteFilter</filter-class> </filter> <filter-mapping> <filter-name>RewriteFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
3. (可选)老版本WebLogic的替代方案
如果你的WebLogic版本低于12c,不支持原生重写模块,可以自己写一个Servlet Filter来实现转发逻辑:
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; public class AngularRoutingFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; String path = req.getRequestURI().substring(req.getContextPath().length()); // 排除静态资源和API接口请求 if (!path.startsWith("/api/") && !path.contains(".") && !path.equals("/")) { request.getRequestDispatcher("/index.html").forward(request, response); return; } chain.doFilter(request, response); } @Override public void destroy() {} }
然后在web.xml中注册这个过滤器:
<filter> <filter-name>AngularRoutingFilter</filter-name> <filter-class>com.yourpackage.AngularRoutingFilter</filter-class> </filter> <filter-mapping> <filter-name>AngularRoutingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
验证效果
配置完成后,重新部署你的Angular应用:
- 直接访问
/dashboard这类路由URL,网络请求中不会再出现404 - 刷新页面也能正常加载对应的路由组件
内容的提问来源于stack exchange,提问作者Iqubal khan

