document.hasFocus() & $(window).blur()

本文探讨了网页中元素焦点管理的方法,包括使用$(window).blur()和document.hasFocus()等技术来检测焦点变化,尤其是在iframe和不同页面间的跳转情况下。同时介绍了能够获取焦点的元素类型及其在不同浏览器中的行为差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

- $(window).blur()

jquery方法:

1.当内嵌iframe时,会触发

2.当弹出上传框时,会触发

3.当出现弹出“是否允许麦克风或摄像头”时,会触发

- document.hasFocus():用于检测文档(或文档内的任一元素)是否获取焦点

1.当内嵌iframe时,不触发

2.当弹出上传框时,会触发

3.当出现弹出“是否允许麦克风或摄像头”时,会触发

方法chrome ie firefox safari  opare
hasFocus()30.06.03.0Yes23.0

 

- document.activeElement:当前文档获取焦点的元素js对象 

 诡异问题:document.activeElement 为 HTMLBodyElement; 但 document.hasFocus() 返回 false;

 场景描述:内嵌外部iframe页面,通过angular 路由跳转到parent window出现上面诡异问题;parent window页面跳转到内嵌iframe的页面正常;

 解决方法:判断路由,非iframe路由强制focus button按钮

        $("button#focus").get(0).focus();

 猜测问题点:document.activeElement当页面没有焦点的时候 默认为 HTMLBodyElement;所以,iframe跳回主页面时并没有焦点;但是主页面跳转到iframe时会自动iframe获取焦点;

- 可以获取焦点的元素(浏览器行为,差异比较大)

  • HTMLAnchorElement/HTMLAreaElement with an href
  • HTMLInputElement/HTMLSelectElement/HTMLTextAreaElement/HTMLButtonElement but not with disabled (IE actually gives you an error if you try), and file uploads have unusual behaviour for security reasons
  • HTMLIFrameElement (though focusing it doesn't do anything useful). Other embedding elements also, maybe, I haven't tested them all.
  • Any element with a tabindex != -1
  • div contentEditable = true
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        .box{
            width: 100px;
            height: 100px;
            background-color: #EEEEEE;
            display: inline-block;
        }
    </style>
    <script type="text/javascript">
        window.onload = function () {
            document.onkeyup = function () {
                console.log(document.activeElement);
            }
        }
    </script>
</head>
<body>
<div class="box" tabindex="-1">tabindex = -1</div>
<div class="box" tabindex="2">tabindex = 2</div>
<span class="box" style="display: block"> display: block</span>
<div class="box" contenteditable="true">contenteditable="true"</div>
<button disabled>disabled</button>
<button>undisabled</button>
<iframe src="wwww.baidu.com" width="100" height="100"></iframe>
</body>
</html>

 

转载于:https://www.cnblogs.com/tianmuxi/p/8744783.html

function https(url,data,fu){ $.ajax({ contentType:&quot;application/json&quot;, url: url, // 假设后端 API 地址 method: &quot;POST&quot;, data: JSON.stringify(data), type: &quot;json&quot;, dataType: &quot;json&quot;, success:function(e){ console.log(e.data) if(e.status==200){ console.log(e.data) fu(e.data) }else{ alert(e.text) } }, error: function (e) { console.log(e.data) console.error(e) alert(&quot;请求失败,请稍后再试!&quot;+e); } }); } function checkLoginStatus() { if (window.location.href.includes(&#39;/login.html&#39;)) return; } window.addEventListener(&#39;beforeunload&#39;, function(e) { console.trace(&#39;触发页面跳转的堆栈跟踪:&#39;); }); //安全验证函数 function validateUserSession() { try { // 防御性数据获取 + 数据清洗 const rawValue = localStorage.getItem(&quot;name&quot;); const username = String(rawValue ?? &#39;&#39;) .trim() .replace(/[\u200B-\u200D\uFEFF]/g, &#39;&#39;); // 移除零宽字符 // 调试信息 console.log(&#39;[Auth] Raw:&#39;, rawValue, &#39;Processed:&#39;, username); // 复合验证条件 const isValid = ( username.length &gt;= 2 &amp;&amp; // 最小长度要求 !/[&lt;&gt;]/.test(username) &amp;&amp; // 防止XSS username !== &#39;null&#39; &amp;&amp; username !== &#39;undefined&#39; ); if (!isValid) { console.warn(&#39;无效用户标识:&#39;, username); // 安全跳转方法 //window.location.replace(&#39;/KuCun2/login.html&#39;); // 立即终止执行 return Promise.reject(&#39;Invalid session&#39;); } // 返回清洗后的用户名 return username; } catch (error) { console.error(&#39;会话验证失败:&#39;, error); // window.location.replace(&#39;/KuCun2/login.html&#39;); return Promise.reject(error); } } function deepMergeArrays(frontend, backend) { const resultMap = new Map(); // 遍历前端数据并存入 Map 中以便快速查找 frontend.forEach(item =&gt; resultMap.set(item.id, { ...item })); // 遍历后端数据并与前端数据进行合并 backend.forEach(item =&gt; { if (resultMap.has(item.id)) { // 如果存在相同 ID,则合并两者的内容 resultMap.set( item.id, Object.assign(resultMap.get(item.id), item) ); } else { // 如果不存在相同 ID,则新增该条目 resultMap.set(item.id, { ...item }); } }); // 将最终结果转回数组形式 return Array.from(resultMap.values()); } (function ($){ // 页面加载时检查登录状态 checkLoginStatus(); })(jQuery); function removeSpecificCharactersAndConvertToNumber(str, charsToRemove) { const regex = new RegExp(`[${charsToRemove}]`, &#39;g&#39;); // 创建用于匹配指定字符的正则表达式 const cleanedStr = str.replace(regex, &#39;&#39;); // 移除指定字符 const numberValue = parseFloat(cleanedStr); // 转换为浮点数 return isNaN(numberValue) ? null : numberValue; // 如果无法解析,则返回 null } &lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt; &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; &lt;groupId&gt;KuCun2&lt;/groupId&gt; &lt;artifactId&gt;KuCun2&lt;/artifactId&gt; &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt; &lt;packaging&gt;war&lt;/packaging&gt; &lt;name&gt;KuCun2&lt;/name&gt; &lt;description/&gt; &lt;parent&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt; &lt;version&gt;2.3.12.RELEASE&lt;/version&gt; &lt;!-- 请根据需要选择版本 --&gt; &lt;relativePath/&gt; &lt;!-- lookup parent from repository --&gt; &lt;/parent&gt; &lt;properties&gt; &lt;webVersion&gt;4.0&lt;/webVersion&gt; &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt; &lt;protobuf.version&gt;3.21.12&lt;/protobuf.version&gt; &lt;/properties&gt; &lt;dependencies&gt; &lt;dependency&gt; &lt;groupId&gt;javax&lt;/groupId&gt; &lt;artifactId&gt;javaee-api&lt;/artifactId&gt; &lt;version&gt;8.0&lt;/version&gt; &lt;scope&gt;provided&lt;/scope&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.glassfish.web&lt;/groupId&gt; &lt;artifactId&gt;javax.servlet.jsp.jstl&lt;/artifactId&gt; &lt;version&gt;1.2.4&lt;/version&gt; &lt;/dependency&gt; &lt;!-- Spring Boot Starter Data JPA --&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;/artifactId&gt; &lt;/dependency&gt; &lt;!-- MySQL Connector --&gt; &lt;dependency&gt; &lt;groupId&gt;mysql&lt;/groupId&gt; &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt; &lt;version&gt;8.0.33&lt;/version&gt; &lt;exclusions&gt; &lt;exclusion&gt; &lt;groupId&gt;com.google.protobuf&lt;/groupId&gt; &lt;artifactId&gt;protobuf-java&lt;/artifactId&gt; &lt;/exclusion&gt; &lt;/exclusions&gt; &lt;/dependency&gt; &lt;!-- Optional: Lombok for reducing boilerplate code --&gt; &lt;dependency&gt; &lt;groupId&gt;org.projectlombok&lt;/groupId&gt; &lt;artifactId&gt;lombok&lt;/artifactId&gt; &lt;optional&gt;true&lt;/optional&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt; &lt;exclusions&gt; &lt;exclusion&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-security&lt;/artifactId&gt; &lt;/exclusion&gt; &lt;/exclusions&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework&lt;/groupId&gt; &lt;artifactId&gt;spring-webmvc&lt;/artifactId&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt; &lt;exclusions&gt; &lt;exclusion&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt; &lt;/exclusion&gt; &lt;/exclusions&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt; &lt;scope&gt;provided&lt;/scope&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt; &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt; &lt;exclusions&gt; &lt;exclusion&gt; &lt;groupId&gt;com.fasterxml.jackson.datatype&lt;/groupId&gt; &lt;artifactId&gt;jackson-datatype-jsr310&lt;/artifactId&gt; &lt;/exclusion&gt; &lt;/exclusions&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;com.fasterxml.jackson.datatype&lt;/groupId&gt; &lt;artifactId&gt;jackson-datatype-jsr310&lt;/artifactId&gt; &lt;/dependency&gt; &lt;!-- Jackson Databind --&gt; &lt;dependency&gt; &lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt; &lt;artifactId&gt;jackson-databind&lt;/artifactId&gt; &lt;/dependency&gt; &lt;!-- Jackson Core --&gt; &lt;dependency&gt; &lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt; &lt;artifactId&gt;jackson-core&lt;/artifactId&gt; &lt;/dependency&gt; &lt;!-- Jackson Annotations --&gt; &lt;dependency&gt; &lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt; &lt;artifactId&gt;jackson-annotations&lt;/artifactId&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.mindrot&lt;/groupId&gt; &lt;artifactId&gt;jbcrypt&lt;/artifactId&gt; &lt;version&gt;0.4&lt;/version&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;com.google.protobuf&lt;/groupId&gt; &lt;artifactId&gt;protobuf-java&lt;/artifactId&gt; &lt;version&gt;${protobuf.version}&lt;/version&gt; &lt;/dependency&gt; &lt;dependency&gt; &lt;groupId&gt;org.yaml&lt;/groupId&gt; &lt;artifactId&gt;snakeyaml&lt;/artifactId&gt; &lt;version&gt;1.30&lt;/version&gt; &lt;!-- 统一版本号 --&gt; &lt;/dependency&gt; &lt;/dependencies&gt; &lt;build&gt; &lt;plugins&gt; &lt;plugin&gt; &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt; &lt;version&gt;2.3.2&lt;/version&gt; &lt;configuration&gt; &lt;source&gt;1.8&lt;/source&gt; &lt;target&gt;1.8&lt;/target&gt; &lt;compilerArgs&gt; &lt;arg&gt;-parameters&lt;/arg&gt; &lt;/compilerArgs&gt; &lt;/configuration&gt; &lt;/plugin&gt; &lt;plugin&gt; &lt;artifactId&gt;maven-war-plugin&lt;/artifactId&gt; &lt;version&gt;2.6&lt;/version&gt; &lt;configuration&gt; &lt;failOnMissingWebXml&gt;false&lt;/failOnMissingWebXml&gt; &lt;/configuration&gt; &lt;/plugin&gt; &lt;/plugins&gt; &lt;/build&gt; &lt;/project&gt; package com.kucun; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @SpringBootApplication( ) public class DemoApplication extends SpringBootServletInitializer { public static void main(String[] args) { // // ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args); // Arrays.stream(ctx.getBeanNamesForType(SecurityFilterChain.class)) // .forEach(System.out::println); // // // // 测试密码加密示例 // BCryptPasswordEncoder encoder = new BCrypt(); // String rawPassword = &quot;987987&quot;; // String encodedPassword = encoder.encode(rawPassword); // System.out.println(&quot;加密后的密码:&quot; + encodedPassword); SpringApplication.run(DemoApplication.class, args); } }package com.kucun.Config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.kucun.Config.Role.RoleConverter; import com.kucun.Config.user.CustomUserDetails; import com.kucun.data.entity.User; import com.kucun.dataDo.UserRepository; /** * 获取数据 * @author Administrator * */ @Service public class CustomUserDetailsService/* implements UserDetailsService */{ // // @Autowired // private UserRepository userRepository; // // @Autowired // private RoleConverter roleConverter; // // public CustomUserDetailsService() { // // super(); // System.out.println(&quot;11111&quot;); // } ///** // * 获取数据库中用户信息 // * @param andy 账号 // * // * @return // * // */ // @Override // public UserDetails loadUserByUsername(String andy) { // System.out.println(andy); // User user = userRepository.findByAndy(andy); // System.out.println(user); // return new CustomUserDetails(user, // roleConverter.convert(user.getRole()) // 关键转换点[^1] // ); // } }package com.kucun.Config; // 2. 基础安全配置 //@Configuration //@EnableWebSecurity // 启用Web安全功能 public class SecurityConfig //extends WebSecurityConfigurerAdapter { // @Override // public void configure(WebSecurity web) { // web.ignoring().antMatchers(&quot;/check-session&quot;); // } // // 添加自定义Controller // @RestController // public static class SessionCheckController { // @GetMapping(&quot;/check-session&quot;) // public ResponseEntity&lt;?&gt; checkSession(HttpServletRequest request) { // return request.getSession(false) != null ? // ResponseEntity.ok().build() : // ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); // } // } // /** // * 核心安全过滤器链配置 // * @param http HTTP安全构建器 // * @return 安全过滤器链 // * @throws Exception 配置异常 // * // * █ 配置逻辑说明: // * 1. authorizeHttpRequests: 定义访问控制规则 // * 2. formLogin: 配置表单登录 // * 3. logout: 配置注销行为 // * 4. exceptionHandling: 处理权限异常[^3] // */ // // // 修正后的配置方法 // @Override // protected void configure(HttpSecurity http) throws Exception { // // // // http // .csrf().disable() // .sessionManagement() // .sessionCreationPolicy(SessionCreationPolicy.ALWAYS) // .invalidSessionUrl(&quot;/login.html?session=invalid&quot;) // .maximumSessions(1) // .maxSessionsPreventsLogin(false) // .and() // .and() // .addFilterBefore(jsonAuthFilter(), UsernamePasswordAuthenticationFilter.class) // 关键配置 // .authorizeRequests() // .antMatchers(&quot;/login.html&quot;, &quot;/users/login&quot;).permitAll() // .antMatchers(&quot;/js/**&quot;, &quot;/css/**&quot;, &quot;/fonts/**&quot;, &quot;/images/**&quot;,&quot;/check-session&quot;,&quot;/main/bootstrap-3.3.7-dist/**&quot;).permitAll() // .antMatchers(&quot;/users/guanli/**&quot;).hasAuthority(&quot;ROLE_ADMIN&quot;) // .anyRequest().authenticated() // .and() // .formLogin().disable() //// .loginPage(&quot;/login.html&quot;) //// .loginProcessingUrl(&quot;/users/login&quot;) //// //// .successHandler(ajaxAuthenticationSuccessHandler()) // 自定义成功处理器 //// .failureHandler(ajaxAuthenticationFailureHandler()) // 自定义失败处理器 //// .defaultSuccessUrl(&quot;/index.html&quot;) //// .failureUrl(&quot;/login.html?error=true&quot;) //// .usernameParameter(&quot;andy&quot;) // 修改用户名参数名 //// .passwordParameter(&quot;pass&quot;) // 修改密码参数名 //// .and() // // .logout() // .logoutUrl(&quot;/logout&quot;) // .logoutSuccessUrl(&quot;/login.html&quot;) // .and() // .csrf() // .ignoringAntMatchers(&quot;/users/login&quot;) // .and() // .headers() // .frameOptions().sameOrigin() // .and() // .exceptionHandling() // .accessDeniedHandler(accessDeniedHandler()); // 统一使用Handler // } // // // // // // // 返回JSON格式的成功响应 // @Bean // public AuthenticationSuccessHandler ajaxAuthenticationSuccessHandler() { // return (request, response, authentication) -&gt; { // // // // // 强制创建服务端会话 // request.getSession(true); // // // // // String contextPath = request.getContextPath(); // HttpSession session = request.getSession(true); // Cookie cookie = new Cookie(&quot;JSESSIONID&quot;, session.getId()); // cookie.setPath(contextPath.isEmpty() ? &quot;/&quot; : contextPath + &quot;/&quot;); // cookie.setMaxAge(1800); // 30分钟 // response.addCookie(cookie); // // // //构建安全响应数据 // Map&lt;String, Object&gt; responseData = new HashMap&lt;&gt;(); // responseData.put(&quot;sessionId&quot;, request.getSession().getId()); // responseData.put(&quot;userInfo&quot;,Collections.unmodifiableMap(new HashMap&lt;String, Object&gt;() {/** // * // */ // private static final long serialVersionUID = 1L; // // { // put(&quot;Name&quot;, ((CustomUserDetails)authentication.getPrincipal()).getName()); // put(&quot;role&quot;, ((CustomUserDetails)authentication.getPrincipal()).getRole()); // }})); // // // // // 统一返回JSON格式 // response.setContentType(MediaType.APPLICATION_JSON_VALUE); // // new ObjectMapper().writeValue(response.getWriter(), responseData); // // // // // // // // // // response.setContentType(MediaType.APPLICATION_JSON_VALUE); // CustomUserDetails userDetails = (CustomUserDetails) authentication.getPrincipal(); // // response.setStatus(HttpStatus.OK.value()); // System.out.println(authentication.getPrincipal()+&quot;&quot;+authentication.getName()); // // if (request.getHeader(&quot;X-Requested-With&quot;) == null) { // 非AJAX请求 // response.sendRedirect(&quot;/index.html&quot;); // } else { // // //String re=userDetails.getUser().toString() // new ObjectMapper().writeValue(response.getWriter(), userDetails.getUser() // ); // // } // // // // // // // }; // } // // // 返回401状态码和错误信息 // @Bean // public AuthenticationFailureHandler ajaxAuthenticationFailureHandler() { // return (request, response, exception) -&gt; { // if (request.getHeader(&quot;X-Requested-With&quot;) == null) { // response.sendRedirect(&quot;/login.html?error=true&quot;); // } else { // response.setStatus(HttpStatus.UNAUTHORIZED.value()); // response.getWriter().write(&quot;{\&quot;error\&quot;:\&quot;Authentication failed\&quot;}&quot;); // } // }; // } // // // 处理未认证请求 // @Bean // public AuthenticationEntryPoint ajaxAuthenticationEntryPoint() { // return (request, response, exception) -&gt; { // if (request.getHeader(&quot;X-Requested-With&quot;) == null) { // response.sendRedirect(&quot;/login.html?error=true&quot;); // } else { // response.setStatus(HttpStatus.UNAUTHORIZED.value()); // response.getWriter().write(&quot;{\&quot;error\&quot;:\&quot;Authentication failed\&quot;}&quot;); // } // }; // } // // // // // // @Bean // public JsonUsernamePasswordAuthenticationFilter jsonAuthFilter() throws Exception { // // JsonUsernamePasswordAuthenticationFilter filter = // new JsonUsernamePasswordAuthenticationFilter(); // filter.setAuthenticationManager(authenticationManagerBean()); // filter.setUsernameParameter(&quot;andy&quot;); // 设置自定义参数名 // filter.setPasswordParameter(&quot;pass&quot;); // filter.setFilterProcessesUrl(&quot;/users/login&quot;); // filter.setAuthenticationSuccessHandler(ajaxAuthenticationSuccessHandler()); // filter.setAuthenticationFailureHandler(ajaxAuthenticationFailureHandler()); // // return filter; // } // // // /** // * 密码编码器(必须配置) // * 使用BCrypt强哈希算法加密 // */ // @Bean // public PasswordEncoder passwordEncoder() { // return new BCryptPasswordEncoder(); // } // // // @Bean // public AccessDeniedHandler accessDeniedHandler() { // System.out.println(&quot;0000&quot;); // return (request, response, ex) -&gt; { // if (!response.isCommitted()) { // response.sendRedirect(&quot;/error/403&quot;); // } // }; // } // // //} // // // // // // //class JsonUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter { // private final ObjectMapper objectMapper = new ObjectMapper(); // // @Override // public Authentication attemptAuthentication(HttpServletRequest request, // HttpServletResponse response) // throws AuthenticationException { // System.out.println(&quot;收到认证请求,路径:&quot; + request.getRequestURI()); // System.out.println(&quot;请求方法:&quot; + request.getMethod()); // System.out.println(&quot;Content-Type:&quot; + request.getContentType()); // if (request.getContentType() != null &amp;&amp; // request.getContentType().startsWith(MediaType.APPLICATION_JSON_VALUE)) { // // try (InputStream is = request.getInputStream()) { // Map&lt;String, String&gt; authMap = objectMapper.readValue(is, Map.class); // // String username = authMap.getOrDefault(getUsernameParameter(), &quot;&quot;); // String password = authMap.getOrDefault(getPasswordParameter(), &quot;&quot;); // // // 调试日志 // System.out.println(&quot;Authentication attempt with: &quot; + username+&#39;_&#39;+ password); // // UsernamePasswordAuthenticationToken authRequest = // new UsernamePasswordAuthenticationToken(username, password); // // setDetails(request, authRequest); // return this.getAuthenticationManager().authenticate(authRequest); // } catch (IOException e) { // throw new AuthenticationServiceException(&quot;认证请求解析失败&quot;, e); // } // } // Authentication aut= super.attemptAuthentication(request, response); // System.out.println(&quot;结果:&quot;+aut.isAuthenticated()); // // return aut; // } } package com.kucun.Config.Role; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import javax.json.Json; import org.springframework.stereotype.Component; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; /** * 权限转化 * @author Administrator * */ @Component public class RoleConverter { // private static final Map&lt;Integer, String&gt; ROLE_MAP = new HashMap&lt;&gt;(); // // @PostConstruct // public void init() { // ROLE_MAP.put(0, &quot;ROLE_ADMIN&quot;); // ROLE_MAP.put(1, &quot;ROLE_USER&quot;); // ROLE_MAP.put(2, &quot;ROLE_MANAGER&quot;); // ROLE_MAP.put(3, &quot;ROLE_AUDITOR&quot;); // } // // public List&lt;GrantedAuthority&gt; convert(int roleCode) { // ObjectMapper mapper = new ObjectMapper(); // try { // System.out.println(mapper.writeValueAsString(Collections.singletonList( // new SimpleGrantedAuthority(ROLE_MAP.getOrDefault(roleCode, &quot;ROLE_GUEST&quot;)))).toString());//输出[{&quot;authority&quot;:&quot;ROLE_ADMIN&quot;}] // } catch (JsonProcessingException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // // return Collections.singletonList( // new SimpleGrantedAuthority(ROLE_MAP.getOrDefault(roleCode, &quot;ROLE_GUEST&quot;)) // ); // } // }package com.kucun.Config.user; import java.util.Collection; import com.kucun.data.entity.User; public class CustomUserDetails /*implements UserDetails*/ { // /** // * // */ // private static final long serialVersionUID = 1L; // private final String andy; // 对应andy字段 // private final String name; // private final int role; // private final String password; // private final User users; // private final Collection&lt;? extends GrantedAuthority&gt; authorities; // // public CustomUserDetails(User user, Collection&lt;? extends GrantedAuthority&gt; authorities) { // this.andy = user.getAndy(); // this.name = user.getName(); // this.role = user.getRole(); // this.password = user.getPass(); // user.setPass(null); // this.users=user; // this.authorities = authorities; // } // // // 实现UserDetails接口方法 // @Override public String getUsername() { return andy; } // @Override public String getPassword() { return password; } // @Override public Collection&lt;? extends GrantedAuthority&gt; getAuthorities() { return authorities; } // // // 自定义字段访问方法 // public String getName() { return name; } // public User getUser() { return users; } // public int getRole() { return role; } // // // 其他必要方法 // @Override public boolean isAccountNonExpired() { return true; } // @Override public boolean isAccountNonLocked() { return true; } // @Override public boolean isCredentialsNonExpired() { return true; } // @Override public boolean isEnabled() { return true; } } &lt;!doctype html&gt; &lt;html&gt; &lt;head&gt; &lt;meta charset=&quot;utf-8&quot;&gt; &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1, maximum-scale=1&quot;&gt; &lt;title&gt;峤丞板材库存管理&lt;/title&gt; &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt; &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;fonts/font-awesome-4.7.0/css/font-awesome.min.css&quot;&gt; &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/util.css&quot;&gt; &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/main.css&quot;&gt; &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/index2.css&quot;&gt; &lt;style type=&quot;text/css&quot;&gt; *{ margin:0; padding:0; } .frame-header { height: 60px; background-color: #23262E; justify-content: space-between; } .frame-header-li{ font-family: Arial, Helvetica, sans-serif; font-size:40px; } .frame-ul{ } .frame-ul li{ border-style: solid; border-width:1px 0px 1px 0px; margin-top: 1px; height: 35px; text-align: center } #username{ position: absolute; right: 0; /* 靠右 */ } .frame-body { position: fixed; top: 60px; right: 0; bottom: 0; left: 0; display: flex; flex-direction: row; } .frame-side { scrollbar-width: none; /* firefox隐藏滚动条 */ -ms-overflow-style: none; /* IE 10+隐藏滚动条 */ overflow-x: hidden; overflow-y: auto; width: 200px; background-color:#9e5; } .frame-side::-webkit-scrollbar { display: none; /* Chrome Safari 隐藏滚动条*/ } .frame-main { flex-grow: 1; background-color:#fff; } .jiaoluo{ margin: auto; margin-right: 0px; } &lt;/style&gt; &lt;/head&gt; &lt;body&gt; &lt;div class=&quot;frame-header&quot;&gt; &lt;a class=&#39;frame-header-li&#39; style=&quot;color:#fff&quot;&gt;峤丞木材仓库管理&lt;/a&gt; &lt;a id=&quot;username&quot; class=&#39;frame-header-li&#39; style=&quot;color:#520&quot;&gt;峤丞木材仓库管理&lt;/a&gt; &lt;button class=&quot;.menu-button&quot; style=&quot;&quot;&gt;注销&lt;/button&gt; &lt;/div&gt; &lt;div class=&quot;frame-body&quot;&gt; &lt;div class=&quot;frame-side&quot;&gt; &lt;ul class=&#39;frame-ul&#39; style=&quot;text-align:center;&quot;&gt; &lt;li &gt;&lt;a href=&quot;main/test.html&quot; target=&quot;main&quot;&gt;首页&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;main/LuRul.html&quot; target=&quot;main&quot;&gt;材料录入&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;main/Guanli.html&quot; target=&quot;main&quot;&gt;材料录入&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/div&gt; &lt;div class=&quot;frame-main&quot;&gt; &lt;!-- 内容主体区域 --&gt; &lt;iframe id=&quot;iframeid&quot; name=&quot;main&quot; src=&quot;main/index.html&quot; width=&quot;100%&quot; height=&quot;100%&quot; frameborder=&quot;0&quot;&gt; &lt;/iframe&gt; &lt;/div&gt; &lt;/div&gt; &lt;/body&gt; &lt;script type=&quot;text/javascript&quot; src=&quot;js/jquery-3.2.1.min.js&quot;&gt;&lt;/script&gt; &lt;script type=&quot;text/javascript&quot; src=&quot;js/jsyilai.js&quot;&gt;&lt;/script&gt; &lt;/html&gt;&lt;!DOCTYPE html&gt; &lt;html lang=&quot;zh-CN&quot;&gt; &lt;head&gt; &lt;title&gt;扁平简洁的登录页面演示_dowebok&lt;/title&gt; &lt;meta charset=&quot;utf-8&quot;&gt; &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt; &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;fonts/font-awesome-4.7.0/css/font-awesome.min.css&quot;&gt; &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/util.css&quot;&gt; &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;css/main.css&quot;&gt; &lt;/head&gt; &lt;body&gt; &lt;div class=&quot;limiter&quot;&gt; &lt;div class=&quot;container-login100&quot;&gt; &lt;div class=&quot;wrap-login100&quot;&gt; &lt;div class=&quot;login100-form-title&quot; style=&quot;background-image: url(images/bg-01.jpg);&quot;&gt; &lt;span class=&quot;login100-form-title-1&quot;&gt;登 录&lt;/span&gt; &lt;/div&gt; &lt;form class=&quot;login100-form validate-form&quot;&gt; &lt;div class=&quot;wrap-input100 validate-input m-b-26&quot; data-validate=&quot;用户名不能为空&quot;&gt; &lt;span class=&quot;label-input100&quot;&gt;用户名&lt;/span&gt; &lt;input class=&quot;input100&quot; type=&quot;text&quot; name=&quot;andy&quot; placeholder=&quot;请输入用户名&quot;&gt; &lt;span class=&quot;focus-input100&quot;&gt;&lt;/span&gt; &lt;/div&gt; &lt;div class=&quot;wrap-input100 validate-input m-b-18&quot; data-validate=&quot;密码不能为空&quot;&gt; &lt;span class=&quot;label-input100&quot;&gt;密码&lt;/span&gt; &lt;input class=&quot;input100&quot; type=&quot;password&quot; name=&quot;pass&quot; placeholder=&quot;请输入用户密码&quot;&gt; &lt;span class=&quot;focus-input100&quot;&gt;&lt;/span&gt; &lt;/div&gt; &lt;div class=&quot;flex-sb-m w-full p-b-30&quot;&gt; &lt;div class=&quot;contact100-form-checkbox&quot;&gt; &lt;input class=&quot;input-checkbox100&quot; id=&quot;ckb1&quot; type=&quot;checkbox&quot; name=&quot;remember-me&quot;&gt; &lt;label class=&quot;label-checkbox100&quot; for=&quot;ckb1&quot;&gt;记住我&lt;/label&gt; &lt;/div&gt; &lt;div&gt; &lt;a href=&quot;javascript:&quot; class=&quot;txt1&quot;&gt;忘记密码?&lt;/a&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class=&quot;container-login100-form-btn&quot;&gt; &lt;button class=&quot;login100-form-btn&quot;&gt;登 录&lt;/button&gt; &lt;/div&gt; &lt;/form&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;script type=&quot;text/javascript&quot;&gt; &lt;/script&gt; &lt;script src=&quot;js/jquery-3.2.1.min.js&quot;&gt;&lt;/script&gt; &lt;script type=&quot;text/javascript&quot; src=&quot;js/jsyilai.js&quot;&gt;&lt;/script&gt; &lt;/body&gt; &lt;/html&gt; yilai.js (function ($) { var pathName = window.location.pathname; console.log(pathName); // 输出类似于 &#39;/index.html&#39; //alert(pathName) switch (pathName){ case &quot;/KuCun2/login.html&quot;: jQuery.getScript(&#39;/KuCun2/js/main.js?&#39;+Date.now()) jQuery.getScript(&#39;/KuCun2/js/login.js?&#39;+Date.now()) break; case &quot;/KuCun2/main/Guanli.html&quot;: jQuery.getScript(&#39;/KuCun2/js/main.js?&#39;+Date.now()) jQuery.getScript(&#39;/KuCun2/js/guanli.js?&#39;+Date.now()) jQuery.getScript(&#39;/KuCun2/main/bootstrap-3.3.7-dist/js/FileSaver.js?&#39;+Date.now()) jQuery.getScript(&#39;/KuCun2/main/bootstrap-3.3.7-dist/js/MyTable.js?&#39;+Date.now()) break; case &quot;/KuCun2/index.html&quot;: jQuery.getScript(&#39;/KuCun2/js/main.js?&#39;+Date.now()) jQuery.getScript(&#39;/KuCun2/js/index.js?&#39;+Date.now()) break; } })(jQuery) main.js function https(url,data,fu){ $.ajax({ contentType:&quot;application/json&quot;, url: url, // 假设后端 API 地址 method: &quot;POST&quot;, data: JSON.stringify(data), type: &quot;json&quot;, dataType: &quot;json&quot;, success:function(e){ console.log(e.data) if(e.status==200){ console.log(e.data) fu(e.data) }else{ alert(e.text) } }, error: function (e) { console.log(e.data) console.error(e) alert(&quot;请求失败,请稍后再试!&quot;+e); } }); } function checkLoginStatus() { if (window.location.href.includes(&#39;/login.html&#39;)) return; } window.addEventListener(&#39;beforeunload&#39;, function(e) { console.trace(&#39;触发页面跳转的堆栈跟踪:&#39;); }); //安全验证函数 function validateUserSession() { try { // 防御性数据获取 + 数据清洗 const rawValue = localStorage.getItem(&quot;name&quot;); const username = String(rawValue ?? &#39;&#39;) .trim() .replace(/[\u200B-\u200D\uFEFF]/g, &#39;&#39;); // 移除零宽字符 // 调试信息 console.log(&#39;[Auth] Raw:&#39;, rawValue, &#39;Processed:&#39;, username); // 复合验证条件 const isValid = ( username.length &gt;= 2 &amp;&amp; // 最小长度要求 !/[&lt;&gt;]/.test(username) &amp;&amp; // 防止XSS username !== &#39;null&#39; &amp;&amp; username !== &#39;undefined&#39; ); if (!isValid) { console.warn(&#39;无效用户标识:&#39;, username); // 安全跳转方法 //window.location.replace(&#39;/KuCun2/login.html&#39;); // 立即终止执行 return Promise.reject(&#39;Invalid session&#39;); } // 返回清洗后的用户名 return username; } catch (error) { console.error(&#39;会话验证失败:&#39;, error); // window.location.replace(&#39;/KuCun2/login.html&#39;); return Promise.reject(error); } } function deepMergeArrays(frontend, backend) { const resultMap = new Map(); // 遍历前端数据并存入 Map 中以便快速查找 frontend.forEach(item =&gt; resultMap.set(item.id, { ...item })); // 遍历后端数据并与前端数据进行合并 backend.forEach(item =&gt; { if (resultMap.has(item.id)) { // 如果存在相同 ID,则合并两者的内容 resultMap.set( item.id, Object.assign(resultMap.get(item.id), item) ); } else { // 如果不存在相同 ID,则新增该条目 resultMap.set(item.id, { ...item }); } }); // 将最终结果转回数组形式 return Array.from(resultMap.values()); } (function ($){ // 页面加载时检查登录状态 checkLoginStatus(); })(jQuery); function removeSpecificCharactersAndConvertToNumber(str, charsToRemove) { const regex = new RegExp(`[${charsToRemove}]`, &#39;g&#39;); // 创建用于匹配指定字符的正则表达式 const cleanedStr = str.replace(regex, &#39;&#39;); // 移除指定字符 const numberValue = parseFloat(cleanedStr); // 转换为浮点数 return isNaN(numberValue) ? null : numberValue; // 如果无法解析,则返回 null } logi.js/// &lt;reference path=&quot;jquery.d.ts&quot; /&gt; // $(document).ready(function(){ // $(&quot;#submit&quot;).click(function(){ // // // $.ajax({ // url:&quot;../users/login&quot;, // async:false, // data:JSON.stringify({ // andy:$(&quot;#andy&quot;).val(), // pass:$(&quot;#pass&quot;).val(), // name:$(&quot;#name&quot;).val()}), // type:&quot;post&quot;, // contentType:&quot;application/json&quot;, // success:function(e){ // alert(e) // } // }); // // // }); // }) (function ($) { &quot;use strict&quot;; /*================================================================== [ Focus Contact2 ]*/ $(&#39;.input100&#39;).each(function () { $(this).on(&#39;blur&#39;, function () { if ($(this).val().trim() != &quot;&quot;) { $(this).addClass(&#39;has-val&#39;); } else { $(this).removeClass(&#39;has-val&#39;); } }) }) /*================================================================== [ Validate ]*/ var input = $(&#39;.validate-input .input100&#39;); $(&#39;.validate-form&#39;).on(&#39;submit&#39;, function (e) { e.preventDefault(); var check = true; for (var i = 0; i &lt; input.length; i++) { if (validate(input[i]) == false) { showValidate(input[i]); check = false; } } confirm(input) if(check) login(input); return check; }); $(&#39;.validate-form .input100&#39;).each(function () { $(this).focus(function () { hideValidate(this); }); }); function validate(input) { if ($(input).attr(&#39;type&#39;) == &#39;email&#39; || $(input).attr(&#39;name&#39;) == &#39;email&#39;) { if ($(input).val().trim().match(/^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{1,5}|[0-9]{1,3})(\]?)$/) == null) { return false; } } else { if ($(input).val().trim() == &#39;&#39;) { return false; } } } function showValidate(input) { var thisAlert = $(input).parent(); alert(input) $(thisAlert).addClass(&#39;alert-validate&#39;); } function hideValidate(input) { var thisAlert = $(input).parent(); $(thisAlert).removeClass(&#39;alert-validate&#39;); } // 登录按钮点击事件 function login(datas) { var data={} datas.each(function(a,element){ data[$(element).attr(&#39;name&#39;)]=$(element).val() }) alert(data.name); //var data={ andy,pass } // 模拟 AJAX 请求 https(&quot;/KuCun2/users/login&quot;,data,function (response) { alert(&quot;122222&quot;); if (response.name) { localStorage.setItem(&quot;name&quot;, response.name); // 保存用户名到本地存储 localStorage.setItem(&quot;role&quot;, response.role); // 保存权限到本地存储 alert( response.name) window.location.href = &#39;/KuCun2/index.html&#39;; } else { alert(&quot;登录失败,请检查用户名和密码!&quot;); } }) }; // 注销按钮点击事件 $(&quot;#logout-btn&quot;).click(function () { localStorage.removeItem(&quot;name&quot;); // 清除本地存储中的用户名 checkLoginStatus(); // 更新登录状态 }); })(jQuery);index.js$().ready(function () { const username = localStorage.getItem(&quot;name&quot;); $(&quot;#username&quot;).text(username) const $username = $(&#39;#username&#39;); const $menuButton = $(&#39;.menu-button&#39;); let hideTimeout = null; // 点击显示按钮 $username.on(&#39;click&#39;, function(e) { e.stopPropagation(); $menuButton.show(); }); // 区域外点击隐藏 $(document).on(&#39;click&#39;, function(e) { if (!$username.add($menuButton).is(e.target) &amp;&amp; $username.has(e.target).length === 0 &amp;&amp; $menuButton.has(e.target).length === 0) { $menuButton.hide(); } }); // 智能隐藏逻辑 const elements = $username.add($menuButton); elements.on(&#39;mouseleave&#39;, function() { hideTimeout = setTimeout(() =&gt; { $menuButton.hide(); }, 200); }).on(&#39;mouseenter&#39;, function() { clearTimeout(hideTimeout); }); var $iframe = $(&#39;&lt;iframe&gt;&#39;) // 使用 jQuery 监听 iframe 的 load 事件 $iframe.on(&#39;load&#39;, function() { try { // 确保 iframe 的内容可以被访问(非跨域情况下) var iframeDocument = $(this).contents(); var result = iframeDocument.find(&#39;body&#39;).text(); // 获取 iframe 内部的内容作为返回值 console.log(&quot;Iframe 加载完成后的返回值:&quot;, result); window.location.href=&quot;/KuCun2/login.html&quot; } catch (error) { console.error(&quot;无法访问 iframe 内容,可能是因为跨域限制:&quot;, error.message); } }); // 将 iframe 添加到文档中 $(&#39;body&#39;).append($iframe); }); guanli.js(function ($) { //checkLoginStatus();//权限 https(&quot;/KuCun2/users/guanli/getusers&quot;,null,function(e){ $(&quot;#DataTable&quot;).remove() const c=[{id:&quot; 序号 &quot;, name:&quot;名字&quot;, andy:&quot;账号&quot;, role:&quot;权限&quot; }] let row = e.length+1; //c.concat(b); //const combinedArray = [c,e]; var r=deepMergeArrays(c,e) console.log(r ) let sclass = &quot;table table-hover&quot;; let bodys=[`&lt;table id=&#39;DataTable&#39; class=&#39;text-center ${sclass}&#39;&gt;`] let table=$(&quot;#TableView&quot;) table.append(bodys) let te= table.find(&quot;table&quot;) $.each(r, function(index, value) { var tr=&quot;&quot; var boo=false if(index==0){var tr=&quot;&lt;thead&gt;&quot;; boo=false} tr+=&quot;&lt;tr&gt;&quot; $.each(value, function(name,val) { if(name!=&quot;pass&quot;){ if(name!=&quot;id&quot;){ tr+=`&lt;td name=&#39;${name}&#39; &gt;&lt;div contenteditable=&#39;${name!=&quot;id&quot;&amp;&amp;boo}&#39; style=&#39;float: left;width: 70%&#39;&gt;${val}&lt;/div&gt;&lt;/td&gt;`; }else{ tr+=`&lt;td name=&#39;${name}&#39; style=&#39;float: left;width: 70%&#39;&gt;${val}&lt;/td&gt;`; } } }) tr+=&quot;&lt;/tr&gt;&quot; if(index==0){ tr+=&quot;&lt;/thead&gt;&quot;} te.append(tr) }); addRight(&quot;#DataTable&quot;); // // let sclass = &quot;table table-striped&quot;; // let bodys=[`&lt;table id=&#39;DataTable&#39; class=&#39;text-center ${sclass}&#39;&gt;`] // // for(let i = -1; i &lt;= row; i++) { // bodys.push(&quot;&lt;tr&gt;&quot;); // // if(i=-1){ // // for(var a in c[0]) { // // var bo= &quot;&lt;td&gt;&lt;div contenteditable=&#39;true&#39; style=&#39;float: left;width: 70%&#39;&gt;&quot;+c[0][a]+&quot;&lt;/div&gt;&quot;; // bodys.push(bo) // // } // // // }else{ // // // for(let j = 0; j &lt;= col; j++) { // if(j == 0) { // var bo = &quot;&lt;td&gt;&lt;div style=&#39;text-align: center;height: 100%&#39;&gt;&quot; + e[i][b[j]] + &quot;#&lt;/div&gt;&lt;/td&gt;&quot;; // bodys.push(bo) // } else { // var bo= &quot;&lt;td&gt;&lt;div contenteditable=&#39;true&#39; style=&#39;text-align: center;height: 100%&#39;&gt;&quot; // + // // &#39;&lt;span class=&quot;glyphicon glyphicon-remove-sign&quot; style=&quot;color: #999;font-size: 16px;&quot; onclick=&quot;Deleterow(this)&quot; aria-hidden=&quot;true&quot;&gt;&lt;/span&gt;&#39; // +&quot;&lt;/div&gt;&lt;/td&gt;&quot;; // bodys.push(bo) // } // } // } // bodys.push( &quot;&lt;/tr&gt;&quot;); // // } // bodys.push(&quot;&lt;/table&gt;&quot;); // var s=bodys.join(&#39;&#39;) // $(&quot;#TableView&quot;).append(s); // addRight(&quot;#DataTable&quot;); // }) })(jQuery) 访问index.html会被重定向到login.html其他以页面不回
最新发布
05-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值