今天把前端采用vue-element-admin与springboot的项目部署到正是线上,在开发线上很OK的,一放上去我的天啊,坑是真的多阿。下面听我一一道来:我这边采用的是nginx服务器部署。
1.首页能显示,F5强刷新页面404空白页。
location / { index index.php index.html index.htm; try_files $uri $uri/ /index.html; }
2.接口出现返回405,404,403错误
a.第一种解决方法
1.打包时修改.env.production中的 VUE_APP_BASE_API改为自己的api路径 VUE_APP_BASE_API = 'http://127.0.0.1:7081/callcenter-api'
注意:这种方法将会产生跨域
b.第二种解决方法 利用nginx反向代理解决,不存在跨域问题 比如 VUE_APP_BASE_API = '/prod-api' nginx配置为 server { listen 8082; server_name localhost; location / { root /ts/xunyou; index index.html index.htm; try_files $uri $uri/ /index.html; } location /prod-api/{ proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://localhost:8087/; //这里是api的真实地址 client_max_body_size 1000m;//上传图片大小限制 } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
3.出现跨域的问题
自定义header头的时候,跨域请求有一个前置请求,method类型OPTIONS。该请求会被shiro拦截,故而应该统统放行。
配置过滤器 private CorsConfiguration buildConfig() { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.setAllowCredentials(true); List<String> list = new ArrayList<>(); list.add("*"); corsConfiguration.setAllowedOrigins(list); corsConfiguration.addAllowedOrigin(CorsConfiguration.ALL); // 1允许任何域名使用 corsConfiguration.addAllowedHeader(CorsConfiguration.ALL); // 2允许任何头 corsConfiguration.addAllowedMethod(CorsConfiguration.ALL); // 3允许任何方法(post、get等) corsConfiguration.addExposedHeader("x-token");/*暴露哪些头部信息 不能用*因为跨域访问默认不能获取全部头部信息*/ corsConfiguration.addExposedHeader("Authorization"); return corsConfiguration; } @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", buildConfig()); // 4 return new CorsFilter(source); } 继承 FormAuthenticationFilter 重写 isAccessAllowed @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { if (request instanceof HttpServletRequest) { if (((HttpServletRequest) request).getMethod().toUpperCase().equals("OPTIONS")) { return true; } } return super.isAccessAllowed(request, response, mappedValue); }
注:登录失效后出现跨域的问题,则需要在响应时加入跨域
@Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { if (request instanceof HttpServletRequest) { if (((HttpServletRequest) request).getMethod().toUpperCase().equals("OPTIONS")) { return true; } } return super.isAccessAllowed(request, response, mappedValue); } @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { if (this.isLoginRequest(request, response)) { return true; } else { HttpServletResponse res = (HttpServletResponse)response; res.setHeader("Access-Control-Allow-Origin", "*"); res.setStatus(HttpServletResponse.SC_OK); res.setCharacterEncoding("UTF-8"); JSONObject json = new JSONObject(R.error(STCode.TOKEN_ILLEGAL_CODE,STCode.TOKEN_ILLEGAL_MSG)); response.setContentType("application/json"); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); out.println(json); out.flush(); out.close(); return false; } }
4.点击导航菜单连接显示正确,按F5刷新页面空白并且报错。
路径问题;将vue.config.js中的 publicPath: '/',即可。打包时需要使用相对路径来处理静态资源